1*f5c631daSSadaf Ebrahimi // Copyright 2015, VIXL authors
2*f5c631daSSadaf Ebrahimi // All rights reserved.
3*f5c631daSSadaf Ebrahimi //
4*f5c631daSSadaf Ebrahimi // Redistribution and use in source and binary forms, with or without
5*f5c631daSSadaf Ebrahimi // modification, are permitted provided that the following conditions are met:
6*f5c631daSSadaf Ebrahimi //
7*f5c631daSSadaf Ebrahimi // * Redistributions of source code must retain the above copyright notice,
8*f5c631daSSadaf Ebrahimi // this list of conditions and the following disclaimer.
9*f5c631daSSadaf Ebrahimi // * Redistributions in binary form must reproduce the above copyright notice,
10*f5c631daSSadaf Ebrahimi // this list of conditions and the following disclaimer in the documentation
11*f5c631daSSadaf Ebrahimi // and/or other materials provided with the distribution.
12*f5c631daSSadaf Ebrahimi // * Neither the name of ARM Limited nor the names of its contributors may be
13*f5c631daSSadaf Ebrahimi // used to endorse or promote products derived from this software without
14*f5c631daSSadaf Ebrahimi // specific prior written permission.
15*f5c631daSSadaf Ebrahimi //
16*f5c631daSSadaf Ebrahimi // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17*f5c631daSSadaf Ebrahimi // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18*f5c631daSSadaf Ebrahimi // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19*f5c631daSSadaf Ebrahimi // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20*f5c631daSSadaf Ebrahimi // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*f5c631daSSadaf Ebrahimi // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22*f5c631daSSadaf Ebrahimi // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23*f5c631daSSadaf Ebrahimi // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24*f5c631daSSadaf Ebrahimi // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25*f5c631daSSadaf Ebrahimi // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*f5c631daSSadaf Ebrahimi
27*f5c631daSSadaf Ebrahimi #ifndef VIXL_AARCH64_MACRO_ASSEMBLER_AARCH64_H_
28*f5c631daSSadaf Ebrahimi #define VIXL_AARCH64_MACRO_ASSEMBLER_AARCH64_H_
29*f5c631daSSadaf Ebrahimi
30*f5c631daSSadaf Ebrahimi #include <algorithm>
31*f5c631daSSadaf Ebrahimi #include <limits>
32*f5c631daSSadaf Ebrahimi
33*f5c631daSSadaf Ebrahimi #include "../code-generation-scopes-vixl.h"
34*f5c631daSSadaf Ebrahimi #include "../globals-vixl.h"
35*f5c631daSSadaf Ebrahimi #include "../macro-assembler-interface.h"
36*f5c631daSSadaf Ebrahimi
37*f5c631daSSadaf Ebrahimi #include "assembler-aarch64.h"
38*f5c631daSSadaf Ebrahimi // Required for runtime call support.
39*f5c631daSSadaf Ebrahimi // TODO: Break this dependency. We should be able to separate out the necessary
40*f5c631daSSadaf Ebrahimi // parts so that we don't need to include the whole simulator header.
41*f5c631daSSadaf Ebrahimi #include "simulator-aarch64.h"
42*f5c631daSSadaf Ebrahimi // Required in order to generate debugging instructions for the simulator. This
43*f5c631daSSadaf Ebrahimi // is needed regardless of whether the simulator is included or not, since
44*f5c631daSSadaf Ebrahimi // generating simulator specific instructions is controlled at runtime.
45*f5c631daSSadaf Ebrahimi #include "simulator-constants-aarch64.h"
46*f5c631daSSadaf Ebrahimi
47*f5c631daSSadaf Ebrahimi
48*f5c631daSSadaf Ebrahimi #define LS_MACRO_LIST(V) \
49*f5c631daSSadaf Ebrahimi V(Ldrb, Register&, rt, LDRB_w) \
50*f5c631daSSadaf Ebrahimi V(Strb, Register&, rt, STRB_w) \
51*f5c631daSSadaf Ebrahimi V(Ldrsb, Register&, rt, rt.Is64Bits() ? LDRSB_x : LDRSB_w) \
52*f5c631daSSadaf Ebrahimi V(Ldrh, Register&, rt, LDRH_w) \
53*f5c631daSSadaf Ebrahimi V(Strh, Register&, rt, STRH_w) \
54*f5c631daSSadaf Ebrahimi V(Ldrsh, Register&, rt, rt.Is64Bits() ? LDRSH_x : LDRSH_w) \
55*f5c631daSSadaf Ebrahimi V(Ldr, CPURegister&, rt, LoadOpFor(rt)) \
56*f5c631daSSadaf Ebrahimi V(Str, CPURegister&, rt, StoreOpFor(rt)) \
57*f5c631daSSadaf Ebrahimi V(Ldrsw, Register&, rt, LDRSW_x)
58*f5c631daSSadaf Ebrahimi
59*f5c631daSSadaf Ebrahimi
60*f5c631daSSadaf Ebrahimi #define LSPAIR_MACRO_LIST(V) \
61*f5c631daSSadaf Ebrahimi V(Ldp, CPURegister&, rt, rt2, LoadPairOpFor(rt, rt2)) \
62*f5c631daSSadaf Ebrahimi V(Stp, CPURegister&, rt, rt2, StorePairOpFor(rt, rt2)) \
63*f5c631daSSadaf Ebrahimi V(Ldpsw, Register&, rt, rt2, LDPSW_x)
64*f5c631daSSadaf Ebrahimi
65*f5c631daSSadaf Ebrahimi namespace vixl {
66*f5c631daSSadaf Ebrahimi namespace aarch64 {
67*f5c631daSSadaf Ebrahimi
68*f5c631daSSadaf Ebrahimi // Forward declaration
69*f5c631daSSadaf Ebrahimi class MacroAssembler;
70*f5c631daSSadaf Ebrahimi class UseScratchRegisterScope;
71*f5c631daSSadaf Ebrahimi
72*f5c631daSSadaf Ebrahimi class Pool {
73*f5c631daSSadaf Ebrahimi public:
Pool(MacroAssembler * masm)74*f5c631daSSadaf Ebrahimi explicit Pool(MacroAssembler* masm)
75*f5c631daSSadaf Ebrahimi : checkpoint_(kNoCheckpointRequired), masm_(masm) {
76*f5c631daSSadaf Ebrahimi Reset();
77*f5c631daSSadaf Ebrahimi }
78*f5c631daSSadaf Ebrahimi
Reset()79*f5c631daSSadaf Ebrahimi void Reset() {
80*f5c631daSSadaf Ebrahimi checkpoint_ = kNoCheckpointRequired;
81*f5c631daSSadaf Ebrahimi monitor_ = 0;
82*f5c631daSSadaf Ebrahimi }
83*f5c631daSSadaf Ebrahimi
Block()84*f5c631daSSadaf Ebrahimi void Block() { monitor_++; }
85*f5c631daSSadaf Ebrahimi void Release();
IsBlocked()86*f5c631daSSadaf Ebrahimi bool IsBlocked() const { return monitor_ != 0; }
87*f5c631daSSadaf Ebrahimi
88*f5c631daSSadaf Ebrahimi static const ptrdiff_t kNoCheckpointRequired = PTRDIFF_MAX;
89*f5c631daSSadaf Ebrahimi
90*f5c631daSSadaf Ebrahimi void SetNextCheckpoint(ptrdiff_t checkpoint);
GetCheckpoint()91*f5c631daSSadaf Ebrahimi ptrdiff_t GetCheckpoint() const { return checkpoint_; }
92*f5c631daSSadaf Ebrahimi VIXL_DEPRECATED("GetCheckpoint", ptrdiff_t checkpoint() const) {
93*f5c631daSSadaf Ebrahimi return GetCheckpoint();
94*f5c631daSSadaf Ebrahimi }
95*f5c631daSSadaf Ebrahimi
96*f5c631daSSadaf Ebrahimi enum EmitOption { kBranchRequired, kNoBranchRequired };
97*f5c631daSSadaf Ebrahimi
98*f5c631daSSadaf Ebrahimi protected:
99*f5c631daSSadaf Ebrahimi // Next buffer offset at which a check is required for this pool.
100*f5c631daSSadaf Ebrahimi ptrdiff_t checkpoint_;
101*f5c631daSSadaf Ebrahimi // Indicates whether the emission of this pool is blocked.
102*f5c631daSSadaf Ebrahimi int monitor_;
103*f5c631daSSadaf Ebrahimi // The MacroAssembler using this pool.
104*f5c631daSSadaf Ebrahimi MacroAssembler* masm_;
105*f5c631daSSadaf Ebrahimi };
106*f5c631daSSadaf Ebrahimi
107*f5c631daSSadaf Ebrahimi
108*f5c631daSSadaf Ebrahimi class LiteralPool : public Pool {
109*f5c631daSSadaf Ebrahimi public:
110*f5c631daSSadaf Ebrahimi explicit LiteralPool(MacroAssembler* masm);
111*f5c631daSSadaf Ebrahimi ~LiteralPool() VIXL_NEGATIVE_TESTING_ALLOW_EXCEPTION;
112*f5c631daSSadaf Ebrahimi void Reset();
113*f5c631daSSadaf Ebrahimi
114*f5c631daSSadaf Ebrahimi void AddEntry(RawLiteral* literal);
IsEmpty()115*f5c631daSSadaf Ebrahimi bool IsEmpty() const { return entries_.empty(); }
116*f5c631daSSadaf Ebrahimi size_t GetSize() const;
117*f5c631daSSadaf Ebrahimi VIXL_DEPRECATED("GetSize", size_t Size() const) { return GetSize(); }
118*f5c631daSSadaf Ebrahimi
119*f5c631daSSadaf Ebrahimi size_t GetMaxSize() const;
120*f5c631daSSadaf Ebrahimi VIXL_DEPRECATED("GetMaxSize", size_t MaxSize() const) { return GetMaxSize(); }
121*f5c631daSSadaf Ebrahimi
122*f5c631daSSadaf Ebrahimi size_t GetOtherPoolsMaxSize() const;
123*f5c631daSSadaf Ebrahimi VIXL_DEPRECATED("GetOtherPoolsMaxSize", size_t OtherPoolsMaxSize() const) {
124*f5c631daSSadaf Ebrahimi return GetOtherPoolsMaxSize();
125*f5c631daSSadaf Ebrahimi }
126*f5c631daSSadaf Ebrahimi
127*f5c631daSSadaf Ebrahimi void CheckEmitFor(size_t amount, EmitOption option = kBranchRequired);
128*f5c631daSSadaf Ebrahimi // Check whether we need to emit the literal pool in order to be able to
129*f5c631daSSadaf Ebrahimi // safely emit a branch with a given range.
130*f5c631daSSadaf Ebrahimi void CheckEmitForBranch(size_t range);
131*f5c631daSSadaf Ebrahimi void Emit(EmitOption option = kNoBranchRequired);
132*f5c631daSSadaf Ebrahimi
133*f5c631daSSadaf Ebrahimi void SetNextRecommendedCheckpoint(ptrdiff_t offset);
134*f5c631daSSadaf Ebrahimi ptrdiff_t GetNextRecommendedCheckpoint();
135*f5c631daSSadaf Ebrahimi VIXL_DEPRECATED("GetNextRecommendedCheckpoint",
136*f5c631daSSadaf Ebrahimi ptrdiff_t NextRecommendedCheckpoint()) {
137*f5c631daSSadaf Ebrahimi return GetNextRecommendedCheckpoint();
138*f5c631daSSadaf Ebrahimi }
139*f5c631daSSadaf Ebrahimi
140*f5c631daSSadaf Ebrahimi void UpdateFirstUse(ptrdiff_t use_position);
141*f5c631daSSadaf Ebrahimi
DeleteOnDestruction(RawLiteral * literal)142*f5c631daSSadaf Ebrahimi void DeleteOnDestruction(RawLiteral* literal) {
143*f5c631daSSadaf Ebrahimi deleted_on_destruction_.push_back(literal);
144*f5c631daSSadaf Ebrahimi }
145*f5c631daSSadaf Ebrahimi
146*f5c631daSSadaf Ebrahimi // Recommended not exact since the pool can be blocked for short periods.
147*f5c631daSSadaf Ebrahimi static const ptrdiff_t kRecommendedLiteralPoolRange = 128 * KBytes;
148*f5c631daSSadaf Ebrahimi
149*f5c631daSSadaf Ebrahimi private:
150*f5c631daSSadaf Ebrahimi std::vector<RawLiteral*> entries_;
151*f5c631daSSadaf Ebrahimi size_t size_;
152*f5c631daSSadaf Ebrahimi ptrdiff_t first_use_;
153*f5c631daSSadaf Ebrahimi // The parent class `Pool` provides a `checkpoint_`, which is the buffer
154*f5c631daSSadaf Ebrahimi // offset before which a check *must* occur. This recommended checkpoint
155*f5c631daSSadaf Ebrahimi // indicates when we would like to start emitting the constant pool. The
156*f5c631daSSadaf Ebrahimi // MacroAssembler can, but does not have to, check the buffer when the
157*f5c631daSSadaf Ebrahimi // checkpoint is reached.
158*f5c631daSSadaf Ebrahimi ptrdiff_t recommended_checkpoint_;
159*f5c631daSSadaf Ebrahimi
160*f5c631daSSadaf Ebrahimi std::vector<RawLiteral*> deleted_on_destruction_;
161*f5c631daSSadaf Ebrahimi };
162*f5c631daSSadaf Ebrahimi
163*f5c631daSSadaf Ebrahimi
GetSize()164*f5c631daSSadaf Ebrahimi inline size_t LiteralPool::GetSize() const {
165*f5c631daSSadaf Ebrahimi // Account for the pool header.
166*f5c631daSSadaf Ebrahimi return size_ + kInstructionSize;
167*f5c631daSSadaf Ebrahimi }
168*f5c631daSSadaf Ebrahimi
169*f5c631daSSadaf Ebrahimi
GetMaxSize()170*f5c631daSSadaf Ebrahimi inline size_t LiteralPool::GetMaxSize() const {
171*f5c631daSSadaf Ebrahimi // Account for the potential branch over the pool.
172*f5c631daSSadaf Ebrahimi return GetSize() + kInstructionSize;
173*f5c631daSSadaf Ebrahimi }
174*f5c631daSSadaf Ebrahimi
175*f5c631daSSadaf Ebrahimi
GetNextRecommendedCheckpoint()176*f5c631daSSadaf Ebrahimi inline ptrdiff_t LiteralPool::GetNextRecommendedCheckpoint() {
177*f5c631daSSadaf Ebrahimi return first_use_ + kRecommendedLiteralPoolRange;
178*f5c631daSSadaf Ebrahimi }
179*f5c631daSSadaf Ebrahimi
180*f5c631daSSadaf Ebrahimi
181*f5c631daSSadaf Ebrahimi class VeneerPool : public Pool {
182*f5c631daSSadaf Ebrahimi public:
VeneerPool(MacroAssembler * masm)183*f5c631daSSadaf Ebrahimi explicit VeneerPool(MacroAssembler* masm) : Pool(masm) {}
184*f5c631daSSadaf Ebrahimi
185*f5c631daSSadaf Ebrahimi void Reset();
186*f5c631daSSadaf Ebrahimi
Block()187*f5c631daSSadaf Ebrahimi void Block() { monitor_++; }
188*f5c631daSSadaf Ebrahimi void Release();
IsBlocked()189*f5c631daSSadaf Ebrahimi bool IsBlocked() const { return monitor_ != 0; }
IsEmpty()190*f5c631daSSadaf Ebrahimi bool IsEmpty() const { return unresolved_branches_.IsEmpty(); }
191*f5c631daSSadaf Ebrahimi
192*f5c631daSSadaf Ebrahimi class BranchInfo {
193*f5c631daSSadaf Ebrahimi public:
BranchInfo()194*f5c631daSSadaf Ebrahimi BranchInfo()
195*f5c631daSSadaf Ebrahimi : first_unreacheable_pc_(0),
196*f5c631daSSadaf Ebrahimi pc_offset_(0),
197*f5c631daSSadaf Ebrahimi label_(NULL),
198*f5c631daSSadaf Ebrahimi branch_type_(UnknownBranchType) {}
BranchInfo(ptrdiff_t offset,Label * label,ImmBranchType branch_type)199*f5c631daSSadaf Ebrahimi BranchInfo(ptrdiff_t offset, Label* label, ImmBranchType branch_type)
200*f5c631daSSadaf Ebrahimi : pc_offset_(offset), label_(label), branch_type_(branch_type) {
201*f5c631daSSadaf Ebrahimi first_unreacheable_pc_ =
202*f5c631daSSadaf Ebrahimi pc_offset_ + Instruction::GetImmBranchForwardRange(branch_type_);
203*f5c631daSSadaf Ebrahimi }
204*f5c631daSSadaf Ebrahimi
IsValidComparison(const BranchInfo & branch_1,const BranchInfo & branch_2)205*f5c631daSSadaf Ebrahimi static bool IsValidComparison(const BranchInfo& branch_1,
206*f5c631daSSadaf Ebrahimi const BranchInfo& branch_2) {
207*f5c631daSSadaf Ebrahimi // BranchInfo are always compared against against other objects with
208*f5c631daSSadaf Ebrahimi // the same branch type.
209*f5c631daSSadaf Ebrahimi if (branch_1.branch_type_ != branch_2.branch_type_) {
210*f5c631daSSadaf Ebrahimi return false;
211*f5c631daSSadaf Ebrahimi }
212*f5c631daSSadaf Ebrahimi // Since we should never have two branch infos with the same offsets, it
213*f5c631daSSadaf Ebrahimi // first looks like we should check that offsets are different. However
214*f5c631daSSadaf Ebrahimi // the operators may also be used to *search* for a branch info in the
215*f5c631daSSadaf Ebrahimi // set.
216*f5c631daSSadaf Ebrahimi bool same_offsets = (branch_1.pc_offset_ == branch_2.pc_offset_);
217*f5c631daSSadaf Ebrahimi return (!same_offsets || ((branch_1.label_ == branch_2.label_) &&
218*f5c631daSSadaf Ebrahimi (branch_1.first_unreacheable_pc_ ==
219*f5c631daSSadaf Ebrahimi branch_2.first_unreacheable_pc_)));
220*f5c631daSSadaf Ebrahimi }
221*f5c631daSSadaf Ebrahimi
222*f5c631daSSadaf Ebrahimi // We must provide comparison operators to work with InvalSet.
223*f5c631daSSadaf Ebrahimi bool operator==(const BranchInfo& other) const {
224*f5c631daSSadaf Ebrahimi VIXL_ASSERT(IsValidComparison(*this, other));
225*f5c631daSSadaf Ebrahimi return pc_offset_ == other.pc_offset_;
226*f5c631daSSadaf Ebrahimi }
227*f5c631daSSadaf Ebrahimi bool operator<(const BranchInfo& other) const {
228*f5c631daSSadaf Ebrahimi VIXL_ASSERT(IsValidComparison(*this, other));
229*f5c631daSSadaf Ebrahimi return pc_offset_ < other.pc_offset_;
230*f5c631daSSadaf Ebrahimi }
231*f5c631daSSadaf Ebrahimi bool operator<=(const BranchInfo& other) const {
232*f5c631daSSadaf Ebrahimi VIXL_ASSERT(IsValidComparison(*this, other));
233*f5c631daSSadaf Ebrahimi return pc_offset_ <= other.pc_offset_;
234*f5c631daSSadaf Ebrahimi }
235*f5c631daSSadaf Ebrahimi bool operator>(const BranchInfo& other) const {
236*f5c631daSSadaf Ebrahimi VIXL_ASSERT(IsValidComparison(*this, other));
237*f5c631daSSadaf Ebrahimi return pc_offset_ > other.pc_offset_;
238*f5c631daSSadaf Ebrahimi }
239*f5c631daSSadaf Ebrahimi
240*f5c631daSSadaf Ebrahimi // First instruction position that is not reachable by the branch using a
241*f5c631daSSadaf Ebrahimi // positive branch offset.
242*f5c631daSSadaf Ebrahimi ptrdiff_t first_unreacheable_pc_;
243*f5c631daSSadaf Ebrahimi // Offset of the branch in the code generation buffer.
244*f5c631daSSadaf Ebrahimi ptrdiff_t pc_offset_;
245*f5c631daSSadaf Ebrahimi // The label branched to.
246*f5c631daSSadaf Ebrahimi Label* label_;
247*f5c631daSSadaf Ebrahimi ImmBranchType branch_type_;
248*f5c631daSSadaf Ebrahimi };
249*f5c631daSSadaf Ebrahimi
BranchTypeUsesVeneers(ImmBranchType type)250*f5c631daSSadaf Ebrahimi bool BranchTypeUsesVeneers(ImmBranchType type) {
251*f5c631daSSadaf Ebrahimi return (type != UnknownBranchType) && (type != UncondBranchType);
252*f5c631daSSadaf Ebrahimi }
253*f5c631daSSadaf Ebrahimi
254*f5c631daSSadaf Ebrahimi void RegisterUnresolvedBranch(ptrdiff_t branch_pos,
255*f5c631daSSadaf Ebrahimi Label* label,
256*f5c631daSSadaf Ebrahimi ImmBranchType branch_type);
257*f5c631daSSadaf Ebrahimi void DeleteUnresolvedBranchInfoForLabel(Label* label);
258*f5c631daSSadaf Ebrahimi
259*f5c631daSSadaf Ebrahimi bool ShouldEmitVeneer(int64_t first_unreacheable_pc, size_t amount);
ShouldEmitVeneers(size_t amount)260*f5c631daSSadaf Ebrahimi bool ShouldEmitVeneers(size_t amount) {
261*f5c631daSSadaf Ebrahimi return ShouldEmitVeneer(unresolved_branches_.GetFirstLimit(), amount);
262*f5c631daSSadaf Ebrahimi }
263*f5c631daSSadaf Ebrahimi
264*f5c631daSSadaf Ebrahimi void CheckEmitFor(size_t amount, EmitOption option = kBranchRequired);
265*f5c631daSSadaf Ebrahimi void Emit(EmitOption option, size_t margin);
266*f5c631daSSadaf Ebrahimi
267*f5c631daSSadaf Ebrahimi // The code size generated for a veneer. Currently one branch instruction.
268*f5c631daSSadaf Ebrahimi // This is for code size checking purposes, and can be extended in the future
269*f5c631daSSadaf Ebrahimi // for example if we decide to add nops between the veneers.
270*f5c631daSSadaf Ebrahimi static const int kVeneerCodeSize = 1 * kInstructionSize;
271*f5c631daSSadaf Ebrahimi // The maximum size of code other than veneers that can be generated when
272*f5c631daSSadaf Ebrahimi // emitting a veneer pool. Currently there can be an additional branch to jump
273*f5c631daSSadaf Ebrahimi // over the pool.
274*f5c631daSSadaf Ebrahimi static const int kPoolNonVeneerCodeSize = 1 * kInstructionSize;
275*f5c631daSSadaf Ebrahimi
UpdateNextCheckPoint()276*f5c631daSSadaf Ebrahimi void UpdateNextCheckPoint() { SetNextCheckpoint(GetNextCheckPoint()); }
277*f5c631daSSadaf Ebrahimi
GetNumberOfPotentialVeneers()278*f5c631daSSadaf Ebrahimi int GetNumberOfPotentialVeneers() const {
279*f5c631daSSadaf Ebrahimi return static_cast<int>(unresolved_branches_.GetSize());
280*f5c631daSSadaf Ebrahimi }
281*f5c631daSSadaf Ebrahimi VIXL_DEPRECATED("GetNumberOfPotentialVeneers",
NumberOfPotentialVeneers()282*f5c631daSSadaf Ebrahimi int NumberOfPotentialVeneers() const) {
283*f5c631daSSadaf Ebrahimi return GetNumberOfPotentialVeneers();
284*f5c631daSSadaf Ebrahimi }
285*f5c631daSSadaf Ebrahimi
GetMaxSize()286*f5c631daSSadaf Ebrahimi size_t GetMaxSize() const {
287*f5c631daSSadaf Ebrahimi return kPoolNonVeneerCodeSize +
288*f5c631daSSadaf Ebrahimi unresolved_branches_.GetSize() * kVeneerCodeSize;
289*f5c631daSSadaf Ebrahimi }
290*f5c631daSSadaf Ebrahimi VIXL_DEPRECATED("GetMaxSize", size_t MaxSize() const) { return GetMaxSize(); }
291*f5c631daSSadaf Ebrahimi
292*f5c631daSSadaf Ebrahimi size_t GetOtherPoolsMaxSize() const;
293*f5c631daSSadaf Ebrahimi VIXL_DEPRECATED("GetOtherPoolsMaxSize", size_t OtherPoolsMaxSize() const) {
294*f5c631daSSadaf Ebrahimi return GetOtherPoolsMaxSize();
295*f5c631daSSadaf Ebrahimi }
296*f5c631daSSadaf Ebrahimi
297*f5c631daSSadaf Ebrahimi static const int kNPreallocatedInfos = 4;
298*f5c631daSSadaf Ebrahimi static const ptrdiff_t kInvalidOffset = PTRDIFF_MAX;
299*f5c631daSSadaf Ebrahimi static const size_t kReclaimFrom = 128;
300*f5c631daSSadaf Ebrahimi static const size_t kReclaimFactor = 16;
301*f5c631daSSadaf Ebrahimi
302*f5c631daSSadaf Ebrahimi private:
303*f5c631daSSadaf Ebrahimi typedef InvalSet<BranchInfo,
304*f5c631daSSadaf Ebrahimi kNPreallocatedInfos,
305*f5c631daSSadaf Ebrahimi ptrdiff_t,
306*f5c631daSSadaf Ebrahimi kInvalidOffset,
307*f5c631daSSadaf Ebrahimi kReclaimFrom,
308*f5c631daSSadaf Ebrahimi kReclaimFactor>
309*f5c631daSSadaf Ebrahimi BranchInfoTypedSetBase;
310*f5c631daSSadaf Ebrahimi typedef InvalSetIterator<BranchInfoTypedSetBase> BranchInfoTypedSetIterBase;
311*f5c631daSSadaf Ebrahimi
312*f5c631daSSadaf Ebrahimi class BranchInfoTypedSet : public BranchInfoTypedSetBase {
313*f5c631daSSadaf Ebrahimi public:
BranchInfoTypedSet()314*f5c631daSSadaf Ebrahimi BranchInfoTypedSet() : BranchInfoTypedSetBase() {}
315*f5c631daSSadaf Ebrahimi
GetFirstLimit()316*f5c631daSSadaf Ebrahimi ptrdiff_t GetFirstLimit() {
317*f5c631daSSadaf Ebrahimi if (empty()) {
318*f5c631daSSadaf Ebrahimi return kInvalidOffset;
319*f5c631daSSadaf Ebrahimi }
320*f5c631daSSadaf Ebrahimi return GetMinElementKey();
321*f5c631daSSadaf Ebrahimi }
322*f5c631daSSadaf Ebrahimi VIXL_DEPRECATED("GetFirstLimit", ptrdiff_t FirstLimit()) {
323*f5c631daSSadaf Ebrahimi return GetFirstLimit();
324*f5c631daSSadaf Ebrahimi }
325*f5c631daSSadaf Ebrahimi };
326*f5c631daSSadaf Ebrahimi
327*f5c631daSSadaf Ebrahimi class BranchInfoTypedSetIterator : public BranchInfoTypedSetIterBase {
328*f5c631daSSadaf Ebrahimi public:
BranchInfoTypedSetIterator()329*f5c631daSSadaf Ebrahimi BranchInfoTypedSetIterator() : BranchInfoTypedSetIterBase(NULL) {}
BranchInfoTypedSetIterator(BranchInfoTypedSet * typed_set)330*f5c631daSSadaf Ebrahimi explicit BranchInfoTypedSetIterator(BranchInfoTypedSet* typed_set)
331*f5c631daSSadaf Ebrahimi : BranchInfoTypedSetIterBase(typed_set) {}
332*f5c631daSSadaf Ebrahimi
333*f5c631daSSadaf Ebrahimi // TODO: Remove these and use the STL-like interface instead.
334*f5c631daSSadaf Ebrahimi using BranchInfoTypedSetIterBase::Advance;
335*f5c631daSSadaf Ebrahimi using BranchInfoTypedSetIterBase::Current;
336*f5c631daSSadaf Ebrahimi };
337*f5c631daSSadaf Ebrahimi
338*f5c631daSSadaf Ebrahimi class BranchInfoSet {
339*f5c631daSSadaf Ebrahimi public:
insert(BranchInfo branch_info)340*f5c631daSSadaf Ebrahimi void insert(BranchInfo branch_info) {
341*f5c631daSSadaf Ebrahimi ImmBranchType type = branch_info.branch_type_;
342*f5c631daSSadaf Ebrahimi VIXL_ASSERT(IsValidBranchType(type));
343*f5c631daSSadaf Ebrahimi typed_set_[BranchIndexFromType(type)].insert(branch_info);
344*f5c631daSSadaf Ebrahimi }
345*f5c631daSSadaf Ebrahimi
erase(BranchInfo branch_info)346*f5c631daSSadaf Ebrahimi void erase(BranchInfo branch_info) {
347*f5c631daSSadaf Ebrahimi if (IsValidBranchType(branch_info.branch_type_)) {
348*f5c631daSSadaf Ebrahimi int index =
349*f5c631daSSadaf Ebrahimi BranchInfoSet::BranchIndexFromType(branch_info.branch_type_);
350*f5c631daSSadaf Ebrahimi typed_set_[index].erase(branch_info);
351*f5c631daSSadaf Ebrahimi }
352*f5c631daSSadaf Ebrahimi }
353*f5c631daSSadaf Ebrahimi
GetSize()354*f5c631daSSadaf Ebrahimi size_t GetSize() const {
355*f5c631daSSadaf Ebrahimi size_t res = 0;
356*f5c631daSSadaf Ebrahimi for (int i = 0; i < kNumberOfTrackedBranchTypes; i++) {
357*f5c631daSSadaf Ebrahimi res += typed_set_[i].size();
358*f5c631daSSadaf Ebrahimi }
359*f5c631daSSadaf Ebrahimi return res;
360*f5c631daSSadaf Ebrahimi }
361*f5c631daSSadaf Ebrahimi VIXL_DEPRECATED("GetSize", size_t size() const) { return GetSize(); }
362*f5c631daSSadaf Ebrahimi
IsEmpty()363*f5c631daSSadaf Ebrahimi bool IsEmpty() const {
364*f5c631daSSadaf Ebrahimi for (int i = 0; i < kNumberOfTrackedBranchTypes; i++) {
365*f5c631daSSadaf Ebrahimi if (!typed_set_[i].empty()) {
366*f5c631daSSadaf Ebrahimi return false;
367*f5c631daSSadaf Ebrahimi }
368*f5c631daSSadaf Ebrahimi }
369*f5c631daSSadaf Ebrahimi return true;
370*f5c631daSSadaf Ebrahimi }
empty()371*f5c631daSSadaf Ebrahimi VIXL_DEPRECATED("IsEmpty", bool empty() const) { return IsEmpty(); }
372*f5c631daSSadaf Ebrahimi
GetFirstLimit()373*f5c631daSSadaf Ebrahimi ptrdiff_t GetFirstLimit() {
374*f5c631daSSadaf Ebrahimi ptrdiff_t res = kInvalidOffset;
375*f5c631daSSadaf Ebrahimi for (int i = 0; i < kNumberOfTrackedBranchTypes; i++) {
376*f5c631daSSadaf Ebrahimi res = std::min(res, typed_set_[i].GetFirstLimit());
377*f5c631daSSadaf Ebrahimi }
378*f5c631daSSadaf Ebrahimi return res;
379*f5c631daSSadaf Ebrahimi }
380*f5c631daSSadaf Ebrahimi VIXL_DEPRECATED("GetFirstLimit", ptrdiff_t FirstLimit()) {
381*f5c631daSSadaf Ebrahimi return GetFirstLimit();
382*f5c631daSSadaf Ebrahimi }
383*f5c631daSSadaf Ebrahimi
Reset()384*f5c631daSSadaf Ebrahimi void Reset() {
385*f5c631daSSadaf Ebrahimi for (int i = 0; i < kNumberOfTrackedBranchTypes; i++) {
386*f5c631daSSadaf Ebrahimi typed_set_[i].clear();
387*f5c631daSSadaf Ebrahimi }
388*f5c631daSSadaf Ebrahimi }
389*f5c631daSSadaf Ebrahimi
BranchTypeFromIndex(int index)390*f5c631daSSadaf Ebrahimi static ImmBranchType BranchTypeFromIndex(int index) {
391*f5c631daSSadaf Ebrahimi switch (index) {
392*f5c631daSSadaf Ebrahimi case 0:
393*f5c631daSSadaf Ebrahimi return CondBranchType;
394*f5c631daSSadaf Ebrahimi case 1:
395*f5c631daSSadaf Ebrahimi return CompareBranchType;
396*f5c631daSSadaf Ebrahimi case 2:
397*f5c631daSSadaf Ebrahimi return TestBranchType;
398*f5c631daSSadaf Ebrahimi default:
399*f5c631daSSadaf Ebrahimi VIXL_UNREACHABLE();
400*f5c631daSSadaf Ebrahimi return UnknownBranchType;
401*f5c631daSSadaf Ebrahimi }
402*f5c631daSSadaf Ebrahimi }
BranchIndexFromType(ImmBranchType branch_type)403*f5c631daSSadaf Ebrahimi static int BranchIndexFromType(ImmBranchType branch_type) {
404*f5c631daSSadaf Ebrahimi switch (branch_type) {
405*f5c631daSSadaf Ebrahimi case CondBranchType:
406*f5c631daSSadaf Ebrahimi return 0;
407*f5c631daSSadaf Ebrahimi case CompareBranchType:
408*f5c631daSSadaf Ebrahimi return 1;
409*f5c631daSSadaf Ebrahimi case TestBranchType:
410*f5c631daSSadaf Ebrahimi return 2;
411*f5c631daSSadaf Ebrahimi default:
412*f5c631daSSadaf Ebrahimi VIXL_UNREACHABLE();
413*f5c631daSSadaf Ebrahimi return 0;
414*f5c631daSSadaf Ebrahimi }
415*f5c631daSSadaf Ebrahimi }
416*f5c631daSSadaf Ebrahimi
IsValidBranchType(ImmBranchType branch_type)417*f5c631daSSadaf Ebrahimi bool IsValidBranchType(ImmBranchType branch_type) {
418*f5c631daSSadaf Ebrahimi return (branch_type != UnknownBranchType) &&
419*f5c631daSSadaf Ebrahimi (branch_type != UncondBranchType);
420*f5c631daSSadaf Ebrahimi }
421*f5c631daSSadaf Ebrahimi
422*f5c631daSSadaf Ebrahimi private:
423*f5c631daSSadaf Ebrahimi static const int kNumberOfTrackedBranchTypes = 3;
424*f5c631daSSadaf Ebrahimi BranchInfoTypedSet typed_set_[kNumberOfTrackedBranchTypes];
425*f5c631daSSadaf Ebrahimi
426*f5c631daSSadaf Ebrahimi friend class VeneerPool;
427*f5c631daSSadaf Ebrahimi friend class BranchInfoSetIterator;
428*f5c631daSSadaf Ebrahimi };
429*f5c631daSSadaf Ebrahimi
430*f5c631daSSadaf Ebrahimi class BranchInfoSetIterator {
431*f5c631daSSadaf Ebrahimi public:
BranchInfoSetIterator(BranchInfoSet * set)432*f5c631daSSadaf Ebrahimi explicit BranchInfoSetIterator(BranchInfoSet* set) : set_(set) {
433*f5c631daSSadaf Ebrahimi for (int i = 0; i < BranchInfoSet::kNumberOfTrackedBranchTypes; i++) {
434*f5c631daSSadaf Ebrahimi new (&sub_iterator_[i])
435*f5c631daSSadaf Ebrahimi BranchInfoTypedSetIterator(&(set_->typed_set_[i]));
436*f5c631daSSadaf Ebrahimi }
437*f5c631daSSadaf Ebrahimi }
438*f5c631daSSadaf Ebrahimi
Current()439*f5c631daSSadaf Ebrahimi VeneerPool::BranchInfo* Current() {
440*f5c631daSSadaf Ebrahimi for (int i = 0; i < BranchInfoSet::kNumberOfTrackedBranchTypes; i++) {
441*f5c631daSSadaf Ebrahimi if (!sub_iterator_[i].Done()) {
442*f5c631daSSadaf Ebrahimi return sub_iterator_[i].Current();
443*f5c631daSSadaf Ebrahimi }
444*f5c631daSSadaf Ebrahimi }
445*f5c631daSSadaf Ebrahimi VIXL_UNREACHABLE();
446*f5c631daSSadaf Ebrahimi return NULL;
447*f5c631daSSadaf Ebrahimi }
448*f5c631daSSadaf Ebrahimi
Advance()449*f5c631daSSadaf Ebrahimi void Advance() {
450*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!Done());
451*f5c631daSSadaf Ebrahimi for (int i = 0; i < BranchInfoSet::kNumberOfTrackedBranchTypes; i++) {
452*f5c631daSSadaf Ebrahimi if (!sub_iterator_[i].Done()) {
453*f5c631daSSadaf Ebrahimi sub_iterator_[i].Advance();
454*f5c631daSSadaf Ebrahimi return;
455*f5c631daSSadaf Ebrahimi }
456*f5c631daSSadaf Ebrahimi }
457*f5c631daSSadaf Ebrahimi VIXL_UNREACHABLE();
458*f5c631daSSadaf Ebrahimi }
459*f5c631daSSadaf Ebrahimi
Done()460*f5c631daSSadaf Ebrahimi bool Done() const {
461*f5c631daSSadaf Ebrahimi for (int i = 0; i < BranchInfoSet::kNumberOfTrackedBranchTypes; i++) {
462*f5c631daSSadaf Ebrahimi if (!sub_iterator_[i].Done()) return false;
463*f5c631daSSadaf Ebrahimi }
464*f5c631daSSadaf Ebrahimi return true;
465*f5c631daSSadaf Ebrahimi }
466*f5c631daSSadaf Ebrahimi
AdvanceToNextType()467*f5c631daSSadaf Ebrahimi void AdvanceToNextType() {
468*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!Done());
469*f5c631daSSadaf Ebrahimi for (int i = 0; i < BranchInfoSet::kNumberOfTrackedBranchTypes; i++) {
470*f5c631daSSadaf Ebrahimi if (!sub_iterator_[i].Done()) {
471*f5c631daSSadaf Ebrahimi sub_iterator_[i].Finish();
472*f5c631daSSadaf Ebrahimi return;
473*f5c631daSSadaf Ebrahimi }
474*f5c631daSSadaf Ebrahimi }
475*f5c631daSSadaf Ebrahimi VIXL_UNREACHABLE();
476*f5c631daSSadaf Ebrahimi }
477*f5c631daSSadaf Ebrahimi
DeleteCurrentAndAdvance()478*f5c631daSSadaf Ebrahimi void DeleteCurrentAndAdvance() {
479*f5c631daSSadaf Ebrahimi for (int i = 0; i < BranchInfoSet::kNumberOfTrackedBranchTypes; i++) {
480*f5c631daSSadaf Ebrahimi if (!sub_iterator_[i].Done()) {
481*f5c631daSSadaf Ebrahimi sub_iterator_[i].DeleteCurrentAndAdvance();
482*f5c631daSSadaf Ebrahimi return;
483*f5c631daSSadaf Ebrahimi }
484*f5c631daSSadaf Ebrahimi }
485*f5c631daSSadaf Ebrahimi }
486*f5c631daSSadaf Ebrahimi
487*f5c631daSSadaf Ebrahimi private:
488*f5c631daSSadaf Ebrahimi BranchInfoSet* set_;
489*f5c631daSSadaf Ebrahimi BranchInfoTypedSetIterator
490*f5c631daSSadaf Ebrahimi sub_iterator_[BranchInfoSet::kNumberOfTrackedBranchTypes];
491*f5c631daSSadaf Ebrahimi };
492*f5c631daSSadaf Ebrahimi
GetNextCheckPoint()493*f5c631daSSadaf Ebrahimi ptrdiff_t GetNextCheckPoint() {
494*f5c631daSSadaf Ebrahimi if (unresolved_branches_.IsEmpty()) {
495*f5c631daSSadaf Ebrahimi return kNoCheckpointRequired;
496*f5c631daSSadaf Ebrahimi } else {
497*f5c631daSSadaf Ebrahimi return unresolved_branches_.GetFirstLimit();
498*f5c631daSSadaf Ebrahimi }
499*f5c631daSSadaf Ebrahimi }
500*f5c631daSSadaf Ebrahimi VIXL_DEPRECATED("GetNextCheckPoint", ptrdiff_t NextCheckPoint()) {
501*f5c631daSSadaf Ebrahimi return GetNextCheckPoint();
502*f5c631daSSadaf Ebrahimi }
503*f5c631daSSadaf Ebrahimi
504*f5c631daSSadaf Ebrahimi // Information about unresolved (forward) branches.
505*f5c631daSSadaf Ebrahimi BranchInfoSet unresolved_branches_;
506*f5c631daSSadaf Ebrahimi };
507*f5c631daSSadaf Ebrahimi
508*f5c631daSSadaf Ebrahimi
509*f5c631daSSadaf Ebrahimi // Helper for common Emission checks.
510*f5c631daSSadaf Ebrahimi // The macro-instruction maps to a single instruction.
511*f5c631daSSadaf Ebrahimi class SingleEmissionCheckScope : public EmissionCheckScope {
512*f5c631daSSadaf Ebrahimi public:
SingleEmissionCheckScope(MacroAssemblerInterface * masm)513*f5c631daSSadaf Ebrahimi explicit SingleEmissionCheckScope(MacroAssemblerInterface* masm)
514*f5c631daSSadaf Ebrahimi : EmissionCheckScope(masm, kInstructionSize) {}
515*f5c631daSSadaf Ebrahimi };
516*f5c631daSSadaf Ebrahimi
517*f5c631daSSadaf Ebrahimi
518*f5c631daSSadaf Ebrahimi // The macro instruction is a "typical" macro-instruction. Typical macro-
519*f5c631daSSadaf Ebrahimi // instruction only emit a few instructions, a few being defined as 8 here.
520*f5c631daSSadaf Ebrahimi class MacroEmissionCheckScope : public EmissionCheckScope {
521*f5c631daSSadaf Ebrahimi public:
MacroEmissionCheckScope(MacroAssemblerInterface * masm)522*f5c631daSSadaf Ebrahimi explicit MacroEmissionCheckScope(MacroAssemblerInterface* masm)
523*f5c631daSSadaf Ebrahimi : EmissionCheckScope(masm, kTypicalMacroInstructionMaxSize) {}
524*f5c631daSSadaf Ebrahimi
525*f5c631daSSadaf Ebrahimi private:
526*f5c631daSSadaf Ebrahimi static const size_t kTypicalMacroInstructionMaxSize = 8 * kInstructionSize;
527*f5c631daSSadaf Ebrahimi };
528*f5c631daSSadaf Ebrahimi
529*f5c631daSSadaf Ebrahimi
530*f5c631daSSadaf Ebrahimi // This scope simplifies the handling of the SVE `movprfx` instruction.
531*f5c631daSSadaf Ebrahimi //
532*f5c631daSSadaf Ebrahimi // If dst.Aliases(src):
533*f5c631daSSadaf Ebrahimi // - Start an ExactAssemblyScope(masm, kInstructionSize).
534*f5c631daSSadaf Ebrahimi // Otherwise:
535*f5c631daSSadaf Ebrahimi // - Start an ExactAssemblyScope(masm, 2 * kInstructionSize).
536*f5c631daSSadaf Ebrahimi // - Generate a suitable `movprfx` instruction.
537*f5c631daSSadaf Ebrahimi //
538*f5c631daSSadaf Ebrahimi // In both cases, the ExactAssemblyScope is left with enough remaining space for
539*f5c631daSSadaf Ebrahimi // exactly one destructive instruction.
540*f5c631daSSadaf Ebrahimi class MovprfxHelperScope : public ExactAssemblyScope {
541*f5c631daSSadaf Ebrahimi public:
542*f5c631daSSadaf Ebrahimi inline MovprfxHelperScope(MacroAssembler* masm,
543*f5c631daSSadaf Ebrahimi const ZRegister& dst,
544*f5c631daSSadaf Ebrahimi const ZRegister& src);
545*f5c631daSSadaf Ebrahimi
546*f5c631daSSadaf Ebrahimi inline MovprfxHelperScope(MacroAssembler* masm,
547*f5c631daSSadaf Ebrahimi const ZRegister& dst,
548*f5c631daSSadaf Ebrahimi const PRegister& pg,
549*f5c631daSSadaf Ebrahimi const ZRegister& src);
550*f5c631daSSadaf Ebrahimi
551*f5c631daSSadaf Ebrahimi // TODO: Implement constructors that examine _all_ sources. If `dst` aliases
552*f5c631daSSadaf Ebrahimi // any other source register, we can't use `movprfx`. This isn't obviously
553*f5c631daSSadaf Ebrahimi // useful, but the MacroAssembler should not generate invalid code for it.
554*f5c631daSSadaf Ebrahimi // Valid behaviour can be implemented using `mov`.
555*f5c631daSSadaf Ebrahimi //
556*f5c631daSSadaf Ebrahimi // The best way to handle this in an instruction-agnostic way is probably to
557*f5c631daSSadaf Ebrahimi // use variadic templates.
558*f5c631daSSadaf Ebrahimi
559*f5c631daSSadaf Ebrahimi private:
ShouldGenerateMovprfx(const ZRegister & dst,const ZRegister & src)560*f5c631daSSadaf Ebrahimi inline bool ShouldGenerateMovprfx(const ZRegister& dst,
561*f5c631daSSadaf Ebrahimi const ZRegister& src) {
562*f5c631daSSadaf Ebrahimi VIXL_ASSERT(AreSameLaneSize(dst, src));
563*f5c631daSSadaf Ebrahimi return !dst.Aliases(src);
564*f5c631daSSadaf Ebrahimi }
565*f5c631daSSadaf Ebrahimi
ShouldGenerateMovprfx(const ZRegister & dst,const PRegister & pg,const ZRegister & src)566*f5c631daSSadaf Ebrahimi inline bool ShouldGenerateMovprfx(const ZRegister& dst,
567*f5c631daSSadaf Ebrahimi const PRegister& pg,
568*f5c631daSSadaf Ebrahimi const ZRegister& src) {
569*f5c631daSSadaf Ebrahimi VIXL_ASSERT(pg.IsMerging() || pg.IsZeroing());
570*f5c631daSSadaf Ebrahimi // We need to emit movprfx in two cases:
571*f5c631daSSadaf Ebrahimi // 1. To give a predicated merging unary instruction zeroing predication.
572*f5c631daSSadaf Ebrahimi // 2. To make destructive instructions constructive.
573*f5c631daSSadaf Ebrahimi //
574*f5c631daSSadaf Ebrahimi // There are no predicated zeroing instructions that can take movprfx, so we
575*f5c631daSSadaf Ebrahimi // will never generate an unnecessary movprfx with this logic.
576*f5c631daSSadaf Ebrahimi return pg.IsZeroing() || ShouldGenerateMovprfx(dst, src);
577*f5c631daSSadaf Ebrahimi }
578*f5c631daSSadaf Ebrahimi };
579*f5c631daSSadaf Ebrahimi
580*f5c631daSSadaf Ebrahimi
581*f5c631daSSadaf Ebrahimi enum BranchType {
582*f5c631daSSadaf Ebrahimi // Copies of architectural conditions.
583*f5c631daSSadaf Ebrahimi // The associated conditions can be used in place of those, the code will
584*f5c631daSSadaf Ebrahimi // take care of reinterpreting them with the correct type.
585*f5c631daSSadaf Ebrahimi integer_eq = eq,
586*f5c631daSSadaf Ebrahimi integer_ne = ne,
587*f5c631daSSadaf Ebrahimi integer_hs = hs,
588*f5c631daSSadaf Ebrahimi integer_lo = lo,
589*f5c631daSSadaf Ebrahimi integer_mi = mi,
590*f5c631daSSadaf Ebrahimi integer_pl = pl,
591*f5c631daSSadaf Ebrahimi integer_vs = vs,
592*f5c631daSSadaf Ebrahimi integer_vc = vc,
593*f5c631daSSadaf Ebrahimi integer_hi = hi,
594*f5c631daSSadaf Ebrahimi integer_ls = ls,
595*f5c631daSSadaf Ebrahimi integer_ge = ge,
596*f5c631daSSadaf Ebrahimi integer_lt = lt,
597*f5c631daSSadaf Ebrahimi integer_gt = gt,
598*f5c631daSSadaf Ebrahimi integer_le = le,
599*f5c631daSSadaf Ebrahimi integer_al = al,
600*f5c631daSSadaf Ebrahimi integer_nv = nv,
601*f5c631daSSadaf Ebrahimi
602*f5c631daSSadaf Ebrahimi // These two are *different* from the architectural codes al and nv.
603*f5c631daSSadaf Ebrahimi // 'always' is used to generate unconditional branches.
604*f5c631daSSadaf Ebrahimi // 'never' is used to not generate a branch (generally as the inverse
605*f5c631daSSadaf Ebrahimi // branch type of 'always).
606*f5c631daSSadaf Ebrahimi always,
607*f5c631daSSadaf Ebrahimi never,
608*f5c631daSSadaf Ebrahimi // cbz and cbnz
609*f5c631daSSadaf Ebrahimi reg_zero,
610*f5c631daSSadaf Ebrahimi reg_not_zero,
611*f5c631daSSadaf Ebrahimi // tbz and tbnz
612*f5c631daSSadaf Ebrahimi reg_bit_clear,
613*f5c631daSSadaf Ebrahimi reg_bit_set,
614*f5c631daSSadaf Ebrahimi
615*f5c631daSSadaf Ebrahimi // Aliases.
616*f5c631daSSadaf Ebrahimi kBranchTypeFirstCondition = eq,
617*f5c631daSSadaf Ebrahimi kBranchTypeLastCondition = nv,
618*f5c631daSSadaf Ebrahimi kBranchTypeFirstUsingReg = reg_zero,
619*f5c631daSSadaf Ebrahimi kBranchTypeFirstUsingBit = reg_bit_clear,
620*f5c631daSSadaf Ebrahimi
621*f5c631daSSadaf Ebrahimi // SVE branch conditions.
622*f5c631daSSadaf Ebrahimi integer_none = eq,
623*f5c631daSSadaf Ebrahimi integer_any = ne,
624*f5c631daSSadaf Ebrahimi integer_nlast = cs,
625*f5c631daSSadaf Ebrahimi integer_last = cc,
626*f5c631daSSadaf Ebrahimi integer_first = mi,
627*f5c631daSSadaf Ebrahimi integer_nfrst = pl,
628*f5c631daSSadaf Ebrahimi integer_pmore = hi,
629*f5c631daSSadaf Ebrahimi integer_plast = ls,
630*f5c631daSSadaf Ebrahimi integer_tcont = ge,
631*f5c631daSSadaf Ebrahimi integer_tstop = lt
632*f5c631daSSadaf Ebrahimi };
633*f5c631daSSadaf Ebrahimi
634*f5c631daSSadaf Ebrahimi
635*f5c631daSSadaf Ebrahimi enum DiscardMoveMode { kDontDiscardForSameWReg, kDiscardForSameWReg };
636*f5c631daSSadaf Ebrahimi
637*f5c631daSSadaf Ebrahimi // The macro assembler supports moving automatically pre-shifted immediates for
638*f5c631daSSadaf Ebrahimi // arithmetic and logical instructions, and then applying a post shift in the
639*f5c631daSSadaf Ebrahimi // instruction to undo the modification, in order to reduce the code emitted for
640*f5c631daSSadaf Ebrahimi // an operation. For example:
641*f5c631daSSadaf Ebrahimi //
642*f5c631daSSadaf Ebrahimi // Add(x0, x0, 0x1f7de) => movz x16, 0xfbef; add x0, x0, x16, lsl #1.
643*f5c631daSSadaf Ebrahimi //
644*f5c631daSSadaf Ebrahimi // This optimisation can be only partially applied when the stack pointer is an
645*f5c631daSSadaf Ebrahimi // operand or destination, so this enumeration is used to control the shift.
646*f5c631daSSadaf Ebrahimi enum PreShiftImmMode {
647*f5c631daSSadaf Ebrahimi kNoShift, // Don't pre-shift.
648*f5c631daSSadaf Ebrahimi kLimitShiftForSP, // Limit pre-shift for add/sub extend use.
649*f5c631daSSadaf Ebrahimi kAnyShift // Allow any pre-shift.
650*f5c631daSSadaf Ebrahimi };
651*f5c631daSSadaf Ebrahimi
652*f5c631daSSadaf Ebrahimi enum FPMacroNaNPropagationOption {
653*f5c631daSSadaf Ebrahimi // The default option. This generates a run-time error in macros that respect
654*f5c631daSSadaf Ebrahimi // this option.
655*f5c631daSSadaf Ebrahimi NoFPMacroNaNPropagationSelected,
656*f5c631daSSadaf Ebrahimi // For example, Fmin(result, NaN(a), NaN(b)) always selects NaN(a) if both
657*f5c631daSSadaf Ebrahimi // NaN(a) and NaN(b) are both quiet, or both are signalling, at the
658*f5c631daSSadaf Ebrahimi // cost of extra code generation in some cases.
659*f5c631daSSadaf Ebrahimi StrictNaNPropagation,
660*f5c631daSSadaf Ebrahimi // For example, Fmin(result, NaN(a), NaN(b)) selects either NaN, but using the
661*f5c631daSSadaf Ebrahimi // fewest instructions.
662*f5c631daSSadaf Ebrahimi FastNaNPropagation
663*f5c631daSSadaf Ebrahimi };
664*f5c631daSSadaf Ebrahimi
665*f5c631daSSadaf Ebrahimi class MacroAssembler : public Assembler, public MacroAssemblerInterface {
666*f5c631daSSadaf Ebrahimi public:
667*f5c631daSSadaf Ebrahimi explicit MacroAssembler(
668*f5c631daSSadaf Ebrahimi PositionIndependentCodeOption pic = PositionIndependentCode);
669*f5c631daSSadaf Ebrahimi MacroAssembler(size_t capacity,
670*f5c631daSSadaf Ebrahimi PositionIndependentCodeOption pic = PositionIndependentCode);
671*f5c631daSSadaf Ebrahimi MacroAssembler(byte* buffer,
672*f5c631daSSadaf Ebrahimi size_t capacity,
673*f5c631daSSadaf Ebrahimi PositionIndependentCodeOption pic = PositionIndependentCode);
674*f5c631daSSadaf Ebrahimi ~MacroAssembler();
675*f5c631daSSadaf Ebrahimi
676*f5c631daSSadaf Ebrahimi enum FinalizeOption {
677*f5c631daSSadaf Ebrahimi kFallThrough, // There may be more code to execute after calling Finalize.
678*f5c631daSSadaf Ebrahimi kUnreachable // Anything generated after calling Finalize is unreachable.
679*f5c631daSSadaf Ebrahimi };
680*f5c631daSSadaf Ebrahimi
AsAssemblerBase()681*f5c631daSSadaf Ebrahimi virtual vixl::internal::AssemblerBase* AsAssemblerBase() VIXL_OVERRIDE {
682*f5c631daSSadaf Ebrahimi return this;
683*f5c631daSSadaf Ebrahimi }
684*f5c631daSSadaf Ebrahimi
685*f5c631daSSadaf Ebrahimi // TODO(pools): implement these functions.
EmitPoolHeader()686*f5c631daSSadaf Ebrahimi virtual void EmitPoolHeader() VIXL_OVERRIDE {}
EmitPoolFooter()687*f5c631daSSadaf Ebrahimi virtual void EmitPoolFooter() VIXL_OVERRIDE {}
EmitPaddingBytes(int n)688*f5c631daSSadaf Ebrahimi virtual void EmitPaddingBytes(int n) VIXL_OVERRIDE { USE(n); }
EmitNopBytes(int n)689*f5c631daSSadaf Ebrahimi virtual void EmitNopBytes(int n) VIXL_OVERRIDE { USE(n); }
690*f5c631daSSadaf Ebrahimi
691*f5c631daSSadaf Ebrahimi // Start generating code from the beginning of the buffer, discarding any code
692*f5c631daSSadaf Ebrahimi // and data that has already been emitted into the buffer.
693*f5c631daSSadaf Ebrahimi //
694*f5c631daSSadaf Ebrahimi // In order to avoid any accidental transfer of state, Reset ASSERTs that the
695*f5c631daSSadaf Ebrahimi // constant pool is not blocked.
696*f5c631daSSadaf Ebrahimi void Reset();
697*f5c631daSSadaf Ebrahimi
698*f5c631daSSadaf Ebrahimi // Finalize a code buffer of generated instructions. This function must be
699*f5c631daSSadaf Ebrahimi // called before executing or copying code from the buffer. By default,
700*f5c631daSSadaf Ebrahimi // anything generated after this should not be reachable (the last instruction
701*f5c631daSSadaf Ebrahimi // generated is an unconditional branch). If you need to generate more code,
702*f5c631daSSadaf Ebrahimi // then set `option` to kFallThrough.
703*f5c631daSSadaf Ebrahimi void FinalizeCode(FinalizeOption option = kUnreachable);
704*f5c631daSSadaf Ebrahimi
705*f5c631daSSadaf Ebrahimi
706*f5c631daSSadaf Ebrahimi // Constant generation helpers.
707*f5c631daSSadaf Ebrahimi // These functions return the number of instructions required to move the
708*f5c631daSSadaf Ebrahimi // immediate into the destination register. Also, if the masm pointer is
709*f5c631daSSadaf Ebrahimi // non-null, it generates the code to do so.
710*f5c631daSSadaf Ebrahimi // The two features are implemented using one function to avoid duplication of
711*f5c631daSSadaf Ebrahimi // the logic.
712*f5c631daSSadaf Ebrahimi // The function can be used to evaluate the cost of synthesizing an
713*f5c631daSSadaf Ebrahimi // instruction using 'mov immediate' instructions. A user might prefer loading
714*f5c631daSSadaf Ebrahimi // a constant using the literal pool instead of using multiple 'mov immediate'
715*f5c631daSSadaf Ebrahimi // instructions.
716*f5c631daSSadaf Ebrahimi static int MoveImmediateHelper(MacroAssembler* masm,
717*f5c631daSSadaf Ebrahimi const Register& rd,
718*f5c631daSSadaf Ebrahimi uint64_t imm);
719*f5c631daSSadaf Ebrahimi
720*f5c631daSSadaf Ebrahimi
721*f5c631daSSadaf Ebrahimi // Logical macros.
722*f5c631daSSadaf Ebrahimi void And(const Register& rd, const Register& rn, const Operand& operand);
723*f5c631daSSadaf Ebrahimi void Ands(const Register& rd, const Register& rn, const Operand& operand);
724*f5c631daSSadaf Ebrahimi void Bic(const Register& rd, const Register& rn, const Operand& operand);
725*f5c631daSSadaf Ebrahimi void Bics(const Register& rd, const Register& rn, const Operand& operand);
726*f5c631daSSadaf Ebrahimi void Orr(const Register& rd, const Register& rn, const Operand& operand);
727*f5c631daSSadaf Ebrahimi void Orn(const Register& rd, const Register& rn, const Operand& operand);
728*f5c631daSSadaf Ebrahimi void Eor(const Register& rd, const Register& rn, const Operand& operand);
729*f5c631daSSadaf Ebrahimi void Eon(const Register& rd, const Register& rn, const Operand& operand);
730*f5c631daSSadaf Ebrahimi void Tst(const Register& rn, const Operand& operand);
731*f5c631daSSadaf Ebrahimi void LogicalMacro(const Register& rd,
732*f5c631daSSadaf Ebrahimi const Register& rn,
733*f5c631daSSadaf Ebrahimi const Operand& operand,
734*f5c631daSSadaf Ebrahimi LogicalOp op);
735*f5c631daSSadaf Ebrahimi
736*f5c631daSSadaf Ebrahimi // Add and sub macros.
737*f5c631daSSadaf Ebrahimi void Add(const Register& rd,
738*f5c631daSSadaf Ebrahimi const Register& rn,
739*f5c631daSSadaf Ebrahimi const Operand& operand,
740*f5c631daSSadaf Ebrahimi FlagsUpdate S = LeaveFlags);
741*f5c631daSSadaf Ebrahimi void Adds(const Register& rd, const Register& rn, const Operand& operand);
742*f5c631daSSadaf Ebrahimi void Sub(const Register& rd,
743*f5c631daSSadaf Ebrahimi const Register& rn,
744*f5c631daSSadaf Ebrahimi const Operand& operand,
745*f5c631daSSadaf Ebrahimi FlagsUpdate S = LeaveFlags);
746*f5c631daSSadaf Ebrahimi void Subs(const Register& rd, const Register& rn, const Operand& operand);
747*f5c631daSSadaf Ebrahimi void Cmn(const Register& rn, const Operand& operand);
748*f5c631daSSadaf Ebrahimi void Cmp(const Register& rn, const Operand& operand);
749*f5c631daSSadaf Ebrahimi void Neg(const Register& rd, const Operand& operand);
750*f5c631daSSadaf Ebrahimi void Negs(const Register& rd, const Operand& operand);
751*f5c631daSSadaf Ebrahimi
752*f5c631daSSadaf Ebrahimi void AddSubMacro(const Register& rd,
753*f5c631daSSadaf Ebrahimi const Register& rn,
754*f5c631daSSadaf Ebrahimi const Operand& operand,
755*f5c631daSSadaf Ebrahimi FlagsUpdate S,
756*f5c631daSSadaf Ebrahimi AddSubOp op);
757*f5c631daSSadaf Ebrahimi
758*f5c631daSSadaf Ebrahimi // Add/sub with carry macros.
759*f5c631daSSadaf Ebrahimi void Adc(const Register& rd, const Register& rn, const Operand& operand);
760*f5c631daSSadaf Ebrahimi void Adcs(const Register& rd, const Register& rn, const Operand& operand);
761*f5c631daSSadaf Ebrahimi void Sbc(const Register& rd, const Register& rn, const Operand& operand);
762*f5c631daSSadaf Ebrahimi void Sbcs(const Register& rd, const Register& rn, const Operand& operand);
763*f5c631daSSadaf Ebrahimi void Ngc(const Register& rd, const Operand& operand);
764*f5c631daSSadaf Ebrahimi void Ngcs(const Register& rd, const Operand& operand);
765*f5c631daSSadaf Ebrahimi void AddSubWithCarryMacro(const Register& rd,
766*f5c631daSSadaf Ebrahimi const Register& rn,
767*f5c631daSSadaf Ebrahimi const Operand& operand,
768*f5c631daSSadaf Ebrahimi FlagsUpdate S,
769*f5c631daSSadaf Ebrahimi AddSubWithCarryOp op);
770*f5c631daSSadaf Ebrahimi
771*f5c631daSSadaf Ebrahimi void Rmif(const Register& xn, unsigned shift, StatusFlags flags);
772*f5c631daSSadaf Ebrahimi void Setf8(const Register& wn);
773*f5c631daSSadaf Ebrahimi void Setf16(const Register& wn);
774*f5c631daSSadaf Ebrahimi
775*f5c631daSSadaf Ebrahimi // Move macros.
776*f5c631daSSadaf Ebrahimi void Mov(const Register& rd, uint64_t imm);
777*f5c631daSSadaf Ebrahimi void Mov(const Register& rd,
778*f5c631daSSadaf Ebrahimi const Operand& operand,
779*f5c631daSSadaf Ebrahimi DiscardMoveMode discard_mode = kDontDiscardForSameWReg);
Mvn(const Register & rd,uint64_t imm)780*f5c631daSSadaf Ebrahimi void Mvn(const Register& rd, uint64_t imm) {
781*f5c631daSSadaf Ebrahimi Mov(rd, (rd.GetSizeInBits() == kXRegSize) ? ~imm : (~imm & kWRegMask));
782*f5c631daSSadaf Ebrahimi }
783*f5c631daSSadaf Ebrahimi void Mvn(const Register& rd, const Operand& operand);
784*f5c631daSSadaf Ebrahimi
785*f5c631daSSadaf Ebrahimi // Try to move an immediate into the destination register in a single
786*f5c631daSSadaf Ebrahimi // instruction. Returns true for success, and updates the contents of dst.
787*f5c631daSSadaf Ebrahimi // Returns false, otherwise.
788*f5c631daSSadaf Ebrahimi bool TryOneInstrMoveImmediate(const Register& dst, uint64_t imm);
789*f5c631daSSadaf Ebrahimi
790*f5c631daSSadaf Ebrahimi // Move an immediate into register dst, and return an Operand object for
791*f5c631daSSadaf Ebrahimi // use with a subsequent instruction that accepts a shift. The value moved
792*f5c631daSSadaf Ebrahimi // into dst is not necessarily equal to imm; it may have had a shifting
793*f5c631daSSadaf Ebrahimi // operation applied to it that will be subsequently undone by the shift
794*f5c631daSSadaf Ebrahimi // applied in the Operand.
795*f5c631daSSadaf Ebrahimi Operand MoveImmediateForShiftedOp(const Register& dst,
796*f5c631daSSadaf Ebrahimi uint64_t imm,
797*f5c631daSSadaf Ebrahimi PreShiftImmMode mode);
798*f5c631daSSadaf Ebrahimi
799*f5c631daSSadaf Ebrahimi void Move(const GenericOperand& dst, const GenericOperand& src);
800*f5c631daSSadaf Ebrahimi
801*f5c631daSSadaf Ebrahimi // Synthesises the address represented by a MemOperand into a register.
802*f5c631daSSadaf Ebrahimi void ComputeAddress(const Register& dst, const MemOperand& mem_op);
803*f5c631daSSadaf Ebrahimi
804*f5c631daSSadaf Ebrahimi // Conditional macros.
805*f5c631daSSadaf Ebrahimi void Ccmp(const Register& rn,
806*f5c631daSSadaf Ebrahimi const Operand& operand,
807*f5c631daSSadaf Ebrahimi StatusFlags nzcv,
808*f5c631daSSadaf Ebrahimi Condition cond);
809*f5c631daSSadaf Ebrahimi void Ccmn(const Register& rn,
810*f5c631daSSadaf Ebrahimi const Operand& operand,
811*f5c631daSSadaf Ebrahimi StatusFlags nzcv,
812*f5c631daSSadaf Ebrahimi Condition cond);
813*f5c631daSSadaf Ebrahimi void ConditionalCompareMacro(const Register& rn,
814*f5c631daSSadaf Ebrahimi const Operand& operand,
815*f5c631daSSadaf Ebrahimi StatusFlags nzcv,
816*f5c631daSSadaf Ebrahimi Condition cond,
817*f5c631daSSadaf Ebrahimi ConditionalCompareOp op);
818*f5c631daSSadaf Ebrahimi
819*f5c631daSSadaf Ebrahimi // On return, the boolean values pointed to will indicate whether `left` and
820*f5c631daSSadaf Ebrahimi // `right` should be synthesised in a temporary register.
GetCselSynthesisInformation(const Register & rd,const Operand & left,const Operand & right,bool * should_synthesise_left,bool * should_synthesise_right)821*f5c631daSSadaf Ebrahimi static void GetCselSynthesisInformation(const Register& rd,
822*f5c631daSSadaf Ebrahimi const Operand& left,
823*f5c631daSSadaf Ebrahimi const Operand& right,
824*f5c631daSSadaf Ebrahimi bool* should_synthesise_left,
825*f5c631daSSadaf Ebrahimi bool* should_synthesise_right) {
826*f5c631daSSadaf Ebrahimi // Note that the helper does not need to look at the condition.
827*f5c631daSSadaf Ebrahimi CselHelper(NULL,
828*f5c631daSSadaf Ebrahimi rd,
829*f5c631daSSadaf Ebrahimi left,
830*f5c631daSSadaf Ebrahimi right,
831*f5c631daSSadaf Ebrahimi eq,
832*f5c631daSSadaf Ebrahimi should_synthesise_left,
833*f5c631daSSadaf Ebrahimi should_synthesise_right);
834*f5c631daSSadaf Ebrahimi }
835*f5c631daSSadaf Ebrahimi
Csel(const Register & rd,const Operand & left,const Operand & right,Condition cond)836*f5c631daSSadaf Ebrahimi void Csel(const Register& rd,
837*f5c631daSSadaf Ebrahimi const Operand& left,
838*f5c631daSSadaf Ebrahimi const Operand& right,
839*f5c631daSSadaf Ebrahimi Condition cond) {
840*f5c631daSSadaf Ebrahimi CselHelper(this, rd, left, right, cond);
841*f5c631daSSadaf Ebrahimi }
842*f5c631daSSadaf Ebrahimi
843*f5c631daSSadaf Ebrahimi // Load/store macros.
844*f5c631daSSadaf Ebrahimi #define DECLARE_FUNCTION(FN, REGTYPE, REG, OP) \
845*f5c631daSSadaf Ebrahimi void FN(const REGTYPE REG, const MemOperand& addr);
846*f5c631daSSadaf Ebrahimi LS_MACRO_LIST(DECLARE_FUNCTION)
847*f5c631daSSadaf Ebrahimi #undef DECLARE_FUNCTION
848*f5c631daSSadaf Ebrahimi
849*f5c631daSSadaf Ebrahimi void LoadStoreMacro(const CPURegister& rt,
850*f5c631daSSadaf Ebrahimi const MemOperand& addr,
851*f5c631daSSadaf Ebrahimi LoadStoreOp op);
852*f5c631daSSadaf Ebrahimi
853*f5c631daSSadaf Ebrahimi #define DECLARE_FUNCTION(FN, REGTYPE, REG, REG2, OP) \
854*f5c631daSSadaf Ebrahimi void FN(const REGTYPE REG, const REGTYPE REG2, const MemOperand& addr);
855*f5c631daSSadaf Ebrahimi LSPAIR_MACRO_LIST(DECLARE_FUNCTION)
856*f5c631daSSadaf Ebrahimi #undef DECLARE_FUNCTION
857*f5c631daSSadaf Ebrahimi
858*f5c631daSSadaf Ebrahimi void LoadStorePairMacro(const CPURegister& rt,
859*f5c631daSSadaf Ebrahimi const CPURegister& rt2,
860*f5c631daSSadaf Ebrahimi const MemOperand& addr,
861*f5c631daSSadaf Ebrahimi LoadStorePairOp op);
862*f5c631daSSadaf Ebrahimi
863*f5c631daSSadaf Ebrahimi void Prfm(PrefetchOperation op, const MemOperand& addr);
864*f5c631daSSadaf Ebrahimi
865*f5c631daSSadaf Ebrahimi // Push or pop up to 4 registers of the same width to or from the stack,
866*f5c631daSSadaf Ebrahimi // using the current stack pointer as set by SetStackPointer.
867*f5c631daSSadaf Ebrahimi //
868*f5c631daSSadaf Ebrahimi // If an argument register is 'NoReg', all further arguments are also assumed
869*f5c631daSSadaf Ebrahimi // to be 'NoReg', and are thus not pushed or popped.
870*f5c631daSSadaf Ebrahimi //
871*f5c631daSSadaf Ebrahimi // Arguments are ordered such that "Push(a, b);" is functionally equivalent
872*f5c631daSSadaf Ebrahimi // to "Push(a); Push(b);".
873*f5c631daSSadaf Ebrahimi //
874*f5c631daSSadaf Ebrahimi // It is valid to push the same register more than once, and there is no
875*f5c631daSSadaf Ebrahimi // restriction on the order in which registers are specified.
876*f5c631daSSadaf Ebrahimi //
877*f5c631daSSadaf Ebrahimi // It is not valid to pop into the same register more than once in one
878*f5c631daSSadaf Ebrahimi // operation, not even into the zero register.
879*f5c631daSSadaf Ebrahimi //
880*f5c631daSSadaf Ebrahimi // If the current stack pointer (as set by SetStackPointer) is sp, then it
881*f5c631daSSadaf Ebrahimi // must be aligned to 16 bytes on entry and the total size of the specified
882*f5c631daSSadaf Ebrahimi // registers must also be a multiple of 16 bytes.
883*f5c631daSSadaf Ebrahimi //
884*f5c631daSSadaf Ebrahimi // Even if the current stack pointer is not the system stack pointer (sp),
885*f5c631daSSadaf Ebrahimi // Push (and derived methods) will still modify the system stack pointer in
886*f5c631daSSadaf Ebrahimi // order to comply with ABI rules about accessing memory below the system
887*f5c631daSSadaf Ebrahimi // stack pointer.
888*f5c631daSSadaf Ebrahimi //
889*f5c631daSSadaf Ebrahimi // Other than the registers passed into Pop, the stack pointer and (possibly)
890*f5c631daSSadaf Ebrahimi // the system stack pointer, these methods do not modify any other registers.
891*f5c631daSSadaf Ebrahimi void Push(const CPURegister& src0,
892*f5c631daSSadaf Ebrahimi const CPURegister& src1 = NoReg,
893*f5c631daSSadaf Ebrahimi const CPURegister& src2 = NoReg,
894*f5c631daSSadaf Ebrahimi const CPURegister& src3 = NoReg);
895*f5c631daSSadaf Ebrahimi void Pop(const CPURegister& dst0,
896*f5c631daSSadaf Ebrahimi const CPURegister& dst1 = NoReg,
897*f5c631daSSadaf Ebrahimi const CPURegister& dst2 = NoReg,
898*f5c631daSSadaf Ebrahimi const CPURegister& dst3 = NoReg);
899*f5c631daSSadaf Ebrahimi
900*f5c631daSSadaf Ebrahimi // Alternative forms of Push and Pop, taking a RegList or CPURegList that
901*f5c631daSSadaf Ebrahimi // specifies the registers that are to be pushed or popped. Higher-numbered
902*f5c631daSSadaf Ebrahimi // registers are associated with higher memory addresses (as in the A32 push
903*f5c631daSSadaf Ebrahimi // and pop instructions).
904*f5c631daSSadaf Ebrahimi //
905*f5c631daSSadaf Ebrahimi // (Push|Pop)SizeRegList allow you to specify the register size as a
906*f5c631daSSadaf Ebrahimi // parameter. Only kXRegSize, kWRegSize, kDRegSize and kSRegSize are
907*f5c631daSSadaf Ebrahimi // supported.
908*f5c631daSSadaf Ebrahimi //
909*f5c631daSSadaf Ebrahimi // Otherwise, (Push|Pop)(CPU|X|W|D|S)RegList is preferred.
910*f5c631daSSadaf Ebrahimi void PushCPURegList(CPURegList registers);
911*f5c631daSSadaf Ebrahimi void PopCPURegList(CPURegList registers);
912*f5c631daSSadaf Ebrahimi
913*f5c631daSSadaf Ebrahimi void PushSizeRegList(
914*f5c631daSSadaf Ebrahimi RegList registers,
915*f5c631daSSadaf Ebrahimi unsigned reg_size,
916*f5c631daSSadaf Ebrahimi CPURegister::RegisterType type = CPURegister::kRegister) {
917*f5c631daSSadaf Ebrahimi PushCPURegList(CPURegList(type, reg_size, registers));
918*f5c631daSSadaf Ebrahimi }
919*f5c631daSSadaf Ebrahimi void PopSizeRegList(RegList registers,
920*f5c631daSSadaf Ebrahimi unsigned reg_size,
921*f5c631daSSadaf Ebrahimi CPURegister::RegisterType type = CPURegister::kRegister) {
922*f5c631daSSadaf Ebrahimi PopCPURegList(CPURegList(type, reg_size, registers));
923*f5c631daSSadaf Ebrahimi }
PushXRegList(RegList regs)924*f5c631daSSadaf Ebrahimi void PushXRegList(RegList regs) { PushSizeRegList(regs, kXRegSize); }
PopXRegList(RegList regs)925*f5c631daSSadaf Ebrahimi void PopXRegList(RegList regs) { PopSizeRegList(regs, kXRegSize); }
PushWRegList(RegList regs)926*f5c631daSSadaf Ebrahimi void PushWRegList(RegList regs) { PushSizeRegList(regs, kWRegSize); }
PopWRegList(RegList regs)927*f5c631daSSadaf Ebrahimi void PopWRegList(RegList regs) { PopSizeRegList(regs, kWRegSize); }
PushDRegList(RegList regs)928*f5c631daSSadaf Ebrahimi void PushDRegList(RegList regs) {
929*f5c631daSSadaf Ebrahimi PushSizeRegList(regs, kDRegSize, CPURegister::kVRegister);
930*f5c631daSSadaf Ebrahimi }
PopDRegList(RegList regs)931*f5c631daSSadaf Ebrahimi void PopDRegList(RegList regs) {
932*f5c631daSSadaf Ebrahimi PopSizeRegList(regs, kDRegSize, CPURegister::kVRegister);
933*f5c631daSSadaf Ebrahimi }
PushSRegList(RegList regs)934*f5c631daSSadaf Ebrahimi void PushSRegList(RegList regs) {
935*f5c631daSSadaf Ebrahimi PushSizeRegList(regs, kSRegSize, CPURegister::kVRegister);
936*f5c631daSSadaf Ebrahimi }
PopSRegList(RegList regs)937*f5c631daSSadaf Ebrahimi void PopSRegList(RegList regs) {
938*f5c631daSSadaf Ebrahimi PopSizeRegList(regs, kSRegSize, CPURegister::kVRegister);
939*f5c631daSSadaf Ebrahimi }
940*f5c631daSSadaf Ebrahimi
941*f5c631daSSadaf Ebrahimi // Push the specified register 'count' times.
942*f5c631daSSadaf Ebrahimi void PushMultipleTimes(int count, Register src);
943*f5c631daSSadaf Ebrahimi
944*f5c631daSSadaf Ebrahimi // Poke 'src' onto the stack. The offset is in bytes.
945*f5c631daSSadaf Ebrahimi //
946*f5c631daSSadaf Ebrahimi // If the current stack pointer (as set by SetStackPointer) is sp, then sp
947*f5c631daSSadaf Ebrahimi // must be aligned to 16 bytes.
948*f5c631daSSadaf Ebrahimi void Poke(const Register& src, const Operand& offset);
949*f5c631daSSadaf Ebrahimi
950*f5c631daSSadaf Ebrahimi // Peek at a value on the stack, and put it in 'dst'. The offset is in bytes.
951*f5c631daSSadaf Ebrahimi //
952*f5c631daSSadaf Ebrahimi // If the current stack pointer (as set by SetStackPointer) is sp, then sp
953*f5c631daSSadaf Ebrahimi // must be aligned to 16 bytes.
954*f5c631daSSadaf Ebrahimi void Peek(const Register& dst, const Operand& offset);
955*f5c631daSSadaf Ebrahimi
956*f5c631daSSadaf Ebrahimi // Alternative forms of Peek and Poke, taking a RegList or CPURegList that
957*f5c631daSSadaf Ebrahimi // specifies the registers that are to be pushed or popped. Higher-numbered
958*f5c631daSSadaf Ebrahimi // registers are associated with higher memory addresses.
959*f5c631daSSadaf Ebrahimi //
960*f5c631daSSadaf Ebrahimi // (Peek|Poke)SizeRegList allow you to specify the register size as a
961*f5c631daSSadaf Ebrahimi // parameter. Only kXRegSize, kWRegSize, kDRegSize and kSRegSize are
962*f5c631daSSadaf Ebrahimi // supported.
963*f5c631daSSadaf Ebrahimi //
964*f5c631daSSadaf Ebrahimi // Otherwise, (Peek|Poke)(CPU|X|W|D|S)RegList is preferred.
PeekCPURegList(CPURegList registers,int64_t offset)965*f5c631daSSadaf Ebrahimi void PeekCPURegList(CPURegList registers, int64_t offset) {
966*f5c631daSSadaf Ebrahimi LoadCPURegList(registers, MemOperand(StackPointer(), offset));
967*f5c631daSSadaf Ebrahimi }
PokeCPURegList(CPURegList registers,int64_t offset)968*f5c631daSSadaf Ebrahimi void PokeCPURegList(CPURegList registers, int64_t offset) {
969*f5c631daSSadaf Ebrahimi StoreCPURegList(registers, MemOperand(StackPointer(), offset));
970*f5c631daSSadaf Ebrahimi }
971*f5c631daSSadaf Ebrahimi
972*f5c631daSSadaf Ebrahimi void PeekSizeRegList(
973*f5c631daSSadaf Ebrahimi RegList registers,
974*f5c631daSSadaf Ebrahimi int64_t offset,
975*f5c631daSSadaf Ebrahimi unsigned reg_size,
976*f5c631daSSadaf Ebrahimi CPURegister::RegisterType type = CPURegister::kRegister) {
977*f5c631daSSadaf Ebrahimi PeekCPURegList(CPURegList(type, reg_size, registers), offset);
978*f5c631daSSadaf Ebrahimi }
979*f5c631daSSadaf Ebrahimi void PokeSizeRegList(
980*f5c631daSSadaf Ebrahimi RegList registers,
981*f5c631daSSadaf Ebrahimi int64_t offset,
982*f5c631daSSadaf Ebrahimi unsigned reg_size,
983*f5c631daSSadaf Ebrahimi CPURegister::RegisterType type = CPURegister::kRegister) {
984*f5c631daSSadaf Ebrahimi PokeCPURegList(CPURegList(type, reg_size, registers), offset);
985*f5c631daSSadaf Ebrahimi }
PeekXRegList(RegList regs,int64_t offset)986*f5c631daSSadaf Ebrahimi void PeekXRegList(RegList regs, int64_t offset) {
987*f5c631daSSadaf Ebrahimi PeekSizeRegList(regs, offset, kXRegSize);
988*f5c631daSSadaf Ebrahimi }
PokeXRegList(RegList regs,int64_t offset)989*f5c631daSSadaf Ebrahimi void PokeXRegList(RegList regs, int64_t offset) {
990*f5c631daSSadaf Ebrahimi PokeSizeRegList(regs, offset, kXRegSize);
991*f5c631daSSadaf Ebrahimi }
PeekWRegList(RegList regs,int64_t offset)992*f5c631daSSadaf Ebrahimi void PeekWRegList(RegList regs, int64_t offset) {
993*f5c631daSSadaf Ebrahimi PeekSizeRegList(regs, offset, kWRegSize);
994*f5c631daSSadaf Ebrahimi }
PokeWRegList(RegList regs,int64_t offset)995*f5c631daSSadaf Ebrahimi void PokeWRegList(RegList regs, int64_t offset) {
996*f5c631daSSadaf Ebrahimi PokeSizeRegList(regs, offset, kWRegSize);
997*f5c631daSSadaf Ebrahimi }
PeekDRegList(RegList regs,int64_t offset)998*f5c631daSSadaf Ebrahimi void PeekDRegList(RegList regs, int64_t offset) {
999*f5c631daSSadaf Ebrahimi PeekSizeRegList(regs, offset, kDRegSize, CPURegister::kVRegister);
1000*f5c631daSSadaf Ebrahimi }
PokeDRegList(RegList regs,int64_t offset)1001*f5c631daSSadaf Ebrahimi void PokeDRegList(RegList regs, int64_t offset) {
1002*f5c631daSSadaf Ebrahimi PokeSizeRegList(regs, offset, kDRegSize, CPURegister::kVRegister);
1003*f5c631daSSadaf Ebrahimi }
PeekSRegList(RegList regs,int64_t offset)1004*f5c631daSSadaf Ebrahimi void PeekSRegList(RegList regs, int64_t offset) {
1005*f5c631daSSadaf Ebrahimi PeekSizeRegList(regs, offset, kSRegSize, CPURegister::kVRegister);
1006*f5c631daSSadaf Ebrahimi }
PokeSRegList(RegList regs,int64_t offset)1007*f5c631daSSadaf Ebrahimi void PokeSRegList(RegList regs, int64_t offset) {
1008*f5c631daSSadaf Ebrahimi PokeSizeRegList(regs, offset, kSRegSize, CPURegister::kVRegister);
1009*f5c631daSSadaf Ebrahimi }
1010*f5c631daSSadaf Ebrahimi
1011*f5c631daSSadaf Ebrahimi
1012*f5c631daSSadaf Ebrahimi // Claim or drop stack space without actually accessing memory.
1013*f5c631daSSadaf Ebrahimi //
1014*f5c631daSSadaf Ebrahimi // If the current stack pointer (as set by SetStackPointer) is sp, then it
1015*f5c631daSSadaf Ebrahimi // must be aligned to 16 bytes and the size claimed or dropped must be a
1016*f5c631daSSadaf Ebrahimi // multiple of 16 bytes.
1017*f5c631daSSadaf Ebrahimi void Claim(const Operand& size);
1018*f5c631daSSadaf Ebrahimi void Drop(const Operand& size);
1019*f5c631daSSadaf Ebrahimi
1020*f5c631daSSadaf Ebrahimi // As above, but for multiples of the SVE vector length.
ClaimVL(int64_t multiplier)1021*f5c631daSSadaf Ebrahimi void ClaimVL(int64_t multiplier) {
1022*f5c631daSSadaf Ebrahimi // We never need to worry about sp alignment because the VL is always a
1023*f5c631daSSadaf Ebrahimi // multiple of 16.
1024*f5c631daSSadaf Ebrahimi VIXL_STATIC_ASSERT((kZRegMinSizeInBytes % 16) == 0);
1025*f5c631daSSadaf Ebrahimi VIXL_ASSERT(multiplier >= 0);
1026*f5c631daSSadaf Ebrahimi Addvl(sp, sp, -multiplier);
1027*f5c631daSSadaf Ebrahimi }
DropVL(int64_t multiplier)1028*f5c631daSSadaf Ebrahimi void DropVL(int64_t multiplier) {
1029*f5c631daSSadaf Ebrahimi VIXL_STATIC_ASSERT((kZRegMinSizeInBytes % 16) == 0);
1030*f5c631daSSadaf Ebrahimi VIXL_ASSERT(multiplier >= 0);
1031*f5c631daSSadaf Ebrahimi Addvl(sp, sp, multiplier);
1032*f5c631daSSadaf Ebrahimi }
1033*f5c631daSSadaf Ebrahimi
1034*f5c631daSSadaf Ebrahimi // Preserve the callee-saved registers (as defined by AAPCS64).
1035*f5c631daSSadaf Ebrahimi //
1036*f5c631daSSadaf Ebrahimi // Higher-numbered registers are pushed before lower-numbered registers, and
1037*f5c631daSSadaf Ebrahimi // thus get higher addresses.
1038*f5c631daSSadaf Ebrahimi // Floating-point registers are pushed before general-purpose registers, and
1039*f5c631daSSadaf Ebrahimi // thus get higher addresses.
1040*f5c631daSSadaf Ebrahimi //
1041*f5c631daSSadaf Ebrahimi // This method must not be called unless StackPointer() is sp, and it is
1042*f5c631daSSadaf Ebrahimi // aligned to 16 bytes.
1043*f5c631daSSadaf Ebrahimi void PushCalleeSavedRegisters();
1044*f5c631daSSadaf Ebrahimi
1045*f5c631daSSadaf Ebrahimi // Restore the callee-saved registers (as defined by AAPCS64).
1046*f5c631daSSadaf Ebrahimi //
1047*f5c631daSSadaf Ebrahimi // Higher-numbered registers are popped after lower-numbered registers, and
1048*f5c631daSSadaf Ebrahimi // thus come from higher addresses.
1049*f5c631daSSadaf Ebrahimi // Floating-point registers are popped after general-purpose registers, and
1050*f5c631daSSadaf Ebrahimi // thus come from higher addresses.
1051*f5c631daSSadaf Ebrahimi //
1052*f5c631daSSadaf Ebrahimi // This method must not be called unless StackPointer() is sp, and it is
1053*f5c631daSSadaf Ebrahimi // aligned to 16 bytes.
1054*f5c631daSSadaf Ebrahimi void PopCalleeSavedRegisters();
1055*f5c631daSSadaf Ebrahimi
1056*f5c631daSSadaf Ebrahimi void LoadCPURegList(CPURegList registers, const MemOperand& src);
1057*f5c631daSSadaf Ebrahimi void StoreCPURegList(CPURegList registers, const MemOperand& dst);
1058*f5c631daSSadaf Ebrahimi
1059*f5c631daSSadaf Ebrahimi // Remaining instructions are simple pass-through calls to the assembler.
Adr(const Register & rd,Label * label)1060*f5c631daSSadaf Ebrahimi void Adr(const Register& rd, Label* label) {
1061*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1062*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1063*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1064*f5c631daSSadaf Ebrahimi adr(rd, label);
1065*f5c631daSSadaf Ebrahimi }
Adrp(const Register & rd,Label * label)1066*f5c631daSSadaf Ebrahimi void Adrp(const Register& rd, Label* label) {
1067*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1068*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1069*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1070*f5c631daSSadaf Ebrahimi adrp(rd, label);
1071*f5c631daSSadaf Ebrahimi }
Asr(const Register & rd,const Register & rn,unsigned shift)1072*f5c631daSSadaf Ebrahimi void Asr(const Register& rd, const Register& rn, unsigned shift) {
1073*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1074*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1075*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
1076*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1077*f5c631daSSadaf Ebrahimi asr(rd, rn, shift);
1078*f5c631daSSadaf Ebrahimi }
Asr(const Register & rd,const Register & rn,const Register & rm)1079*f5c631daSSadaf Ebrahimi void Asr(const Register& rd, const Register& rn, const Register& rm) {
1080*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1081*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1082*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
1083*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rm.IsZero());
1084*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1085*f5c631daSSadaf Ebrahimi asrv(rd, rn, rm);
1086*f5c631daSSadaf Ebrahimi }
1087*f5c631daSSadaf Ebrahimi
1088*f5c631daSSadaf Ebrahimi // Branch type inversion relies on these relations.
1089*f5c631daSSadaf Ebrahimi VIXL_STATIC_ASSERT((reg_zero == (reg_not_zero ^ 1)) &&
1090*f5c631daSSadaf Ebrahimi (reg_bit_clear == (reg_bit_set ^ 1)) &&
1091*f5c631daSSadaf Ebrahimi (always == (never ^ 1)));
1092*f5c631daSSadaf Ebrahimi
InvertBranchType(BranchType type)1093*f5c631daSSadaf Ebrahimi BranchType InvertBranchType(BranchType type) {
1094*f5c631daSSadaf Ebrahimi if (kBranchTypeFirstCondition <= type && type <= kBranchTypeLastCondition) {
1095*f5c631daSSadaf Ebrahimi return static_cast<BranchType>(
1096*f5c631daSSadaf Ebrahimi InvertCondition(static_cast<Condition>(type)));
1097*f5c631daSSadaf Ebrahimi } else {
1098*f5c631daSSadaf Ebrahimi return static_cast<BranchType>(type ^ 1);
1099*f5c631daSSadaf Ebrahimi }
1100*f5c631daSSadaf Ebrahimi }
1101*f5c631daSSadaf Ebrahimi
1102*f5c631daSSadaf Ebrahimi void B(Label* label, BranchType type, Register reg = NoReg, int bit = -1);
1103*f5c631daSSadaf Ebrahimi
1104*f5c631daSSadaf Ebrahimi void B(Label* label);
1105*f5c631daSSadaf Ebrahimi void B(Label* label, Condition cond);
B(Condition cond,Label * label)1106*f5c631daSSadaf Ebrahimi void B(Condition cond, Label* label) { B(label, cond); }
Bfm(const Register & rd,const Register & rn,unsigned immr,unsigned imms)1107*f5c631daSSadaf Ebrahimi void Bfm(const Register& rd,
1108*f5c631daSSadaf Ebrahimi const Register& rn,
1109*f5c631daSSadaf Ebrahimi unsigned immr,
1110*f5c631daSSadaf Ebrahimi unsigned imms) {
1111*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1112*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1113*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
1114*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1115*f5c631daSSadaf Ebrahimi bfm(rd, rn, immr, imms);
1116*f5c631daSSadaf Ebrahimi }
Bfi(const Register & rd,const Register & rn,unsigned lsb,unsigned width)1117*f5c631daSSadaf Ebrahimi void Bfi(const Register& rd,
1118*f5c631daSSadaf Ebrahimi const Register& rn,
1119*f5c631daSSadaf Ebrahimi unsigned lsb,
1120*f5c631daSSadaf Ebrahimi unsigned width) {
1121*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1122*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1123*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
1124*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1125*f5c631daSSadaf Ebrahimi bfi(rd, rn, lsb, width);
1126*f5c631daSSadaf Ebrahimi }
Bfc(const Register & rd,unsigned lsb,unsigned width)1127*f5c631daSSadaf Ebrahimi void Bfc(const Register& rd, unsigned lsb, unsigned width) {
1128*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1129*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1130*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1131*f5c631daSSadaf Ebrahimi bfc(rd, lsb, width);
1132*f5c631daSSadaf Ebrahimi }
Bfxil(const Register & rd,const Register & rn,unsigned lsb,unsigned width)1133*f5c631daSSadaf Ebrahimi void Bfxil(const Register& rd,
1134*f5c631daSSadaf Ebrahimi const Register& rn,
1135*f5c631daSSadaf Ebrahimi unsigned lsb,
1136*f5c631daSSadaf Ebrahimi unsigned width) {
1137*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1138*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1139*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
1140*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1141*f5c631daSSadaf Ebrahimi bfxil(rd, rn, lsb, width);
1142*f5c631daSSadaf Ebrahimi }
1143*f5c631daSSadaf Ebrahimi void Bind(Label* label, BranchTargetIdentifier id = EmitBTI_none);
1144*f5c631daSSadaf Ebrahimi // Bind a label to a specified offset from the start of the buffer.
1145*f5c631daSSadaf Ebrahimi void BindToOffset(Label* label, ptrdiff_t offset);
Bl(Label * label)1146*f5c631daSSadaf Ebrahimi void Bl(Label* label) {
1147*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1148*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1149*f5c631daSSadaf Ebrahimi bl(label);
1150*f5c631daSSadaf Ebrahimi }
Blr(const Register & xn)1151*f5c631daSSadaf Ebrahimi void Blr(const Register& xn) {
1152*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1153*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!xn.IsZero());
1154*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1155*f5c631daSSadaf Ebrahimi blr(xn);
1156*f5c631daSSadaf Ebrahimi }
Br(const Register & xn)1157*f5c631daSSadaf Ebrahimi void Br(const Register& xn) {
1158*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1159*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!xn.IsZero());
1160*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1161*f5c631daSSadaf Ebrahimi br(xn);
1162*f5c631daSSadaf Ebrahimi }
Braaz(const Register & xn)1163*f5c631daSSadaf Ebrahimi void Braaz(const Register& xn) {
1164*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1165*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1166*f5c631daSSadaf Ebrahimi braaz(xn);
1167*f5c631daSSadaf Ebrahimi }
Brabz(const Register & xn)1168*f5c631daSSadaf Ebrahimi void Brabz(const Register& xn) {
1169*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1170*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1171*f5c631daSSadaf Ebrahimi brabz(xn);
1172*f5c631daSSadaf Ebrahimi }
Blraaz(const Register & xn)1173*f5c631daSSadaf Ebrahimi void Blraaz(const Register& xn) {
1174*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1175*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1176*f5c631daSSadaf Ebrahimi blraaz(xn);
1177*f5c631daSSadaf Ebrahimi }
Blrabz(const Register & xn)1178*f5c631daSSadaf Ebrahimi void Blrabz(const Register& xn) {
1179*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1180*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1181*f5c631daSSadaf Ebrahimi blrabz(xn);
1182*f5c631daSSadaf Ebrahimi }
Retaa()1183*f5c631daSSadaf Ebrahimi void Retaa() {
1184*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1185*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1186*f5c631daSSadaf Ebrahimi retaa();
1187*f5c631daSSadaf Ebrahimi }
Retab()1188*f5c631daSSadaf Ebrahimi void Retab() {
1189*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1190*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1191*f5c631daSSadaf Ebrahimi retab();
1192*f5c631daSSadaf Ebrahimi }
Braa(const Register & xn,const Register & xm)1193*f5c631daSSadaf Ebrahimi void Braa(const Register& xn, const Register& xm) {
1194*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1195*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1196*f5c631daSSadaf Ebrahimi braa(xn, xm);
1197*f5c631daSSadaf Ebrahimi }
Brab(const Register & xn,const Register & xm)1198*f5c631daSSadaf Ebrahimi void Brab(const Register& xn, const Register& xm) {
1199*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1200*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1201*f5c631daSSadaf Ebrahimi brab(xn, xm);
1202*f5c631daSSadaf Ebrahimi }
Blraa(const Register & xn,const Register & xm)1203*f5c631daSSadaf Ebrahimi void Blraa(const Register& xn, const Register& xm) {
1204*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1205*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1206*f5c631daSSadaf Ebrahimi blraa(xn, xm);
1207*f5c631daSSadaf Ebrahimi }
Blrab(const Register & xn,const Register & xm)1208*f5c631daSSadaf Ebrahimi void Blrab(const Register& xn, const Register& xm) {
1209*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1210*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1211*f5c631daSSadaf Ebrahimi blrab(xn, xm);
1212*f5c631daSSadaf Ebrahimi }
1213*f5c631daSSadaf Ebrahimi void Brk(int code = 0) {
1214*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1215*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1216*f5c631daSSadaf Ebrahimi brk(code);
1217*f5c631daSSadaf Ebrahimi }
1218*f5c631daSSadaf Ebrahimi void Cbnz(const Register& rt, Label* label);
1219*f5c631daSSadaf Ebrahimi void Cbz(const Register& rt, Label* label);
Cinc(const Register & rd,const Register & rn,Condition cond)1220*f5c631daSSadaf Ebrahimi void Cinc(const Register& rd, const Register& rn, Condition cond) {
1221*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1222*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1223*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
1224*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1225*f5c631daSSadaf Ebrahimi cinc(rd, rn, cond);
1226*f5c631daSSadaf Ebrahimi }
Cinv(const Register & rd,const Register & rn,Condition cond)1227*f5c631daSSadaf Ebrahimi void Cinv(const Register& rd, const Register& rn, Condition cond) {
1228*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1229*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1230*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
1231*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1232*f5c631daSSadaf Ebrahimi cinv(rd, rn, cond);
1233*f5c631daSSadaf Ebrahimi }
1234*f5c631daSSadaf Ebrahimi
1235*f5c631daSSadaf Ebrahimi #define PAUTH_SYSTEM_MODES(V) \
1236*f5c631daSSadaf Ebrahimi V(az) \
1237*f5c631daSSadaf Ebrahimi V(bz) \
1238*f5c631daSSadaf Ebrahimi V(asp) \
1239*f5c631daSSadaf Ebrahimi V(bsp)
1240*f5c631daSSadaf Ebrahimi
1241*f5c631daSSadaf Ebrahimi #define DEFINE_MACRO_ASM_FUNCS(SUFFIX) \
1242*f5c631daSSadaf Ebrahimi void Paci##SUFFIX() { \
1243*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_); \
1244*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this); \
1245*f5c631daSSadaf Ebrahimi paci##SUFFIX(); \
1246*f5c631daSSadaf Ebrahimi } \
1247*f5c631daSSadaf Ebrahimi void Auti##SUFFIX() { \
1248*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_); \
1249*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this); \
1250*f5c631daSSadaf Ebrahimi auti##SUFFIX(); \
1251*f5c631daSSadaf Ebrahimi }
1252*f5c631daSSadaf Ebrahimi
PAUTH_SYSTEM_MODES(DEFINE_MACRO_ASM_FUNCS)1253*f5c631daSSadaf Ebrahimi PAUTH_SYSTEM_MODES(DEFINE_MACRO_ASM_FUNCS)
1254*f5c631daSSadaf Ebrahimi #undef DEFINE_MACRO_ASM_FUNCS
1255*f5c631daSSadaf Ebrahimi
1256*f5c631daSSadaf Ebrahimi // The 1716 pac and aut instructions encourage people to use x16 and x17
1257*f5c631daSSadaf Ebrahimi // directly, perhaps without realising that this is forbidden. For example:
1258*f5c631daSSadaf Ebrahimi //
1259*f5c631daSSadaf Ebrahimi // UseScratchRegisterScope temps(&masm);
1260*f5c631daSSadaf Ebrahimi // Register temp = temps.AcquireX(); // temp will be x16
1261*f5c631daSSadaf Ebrahimi // __ Mov(x17, ptr);
1262*f5c631daSSadaf Ebrahimi // __ Mov(x16, modifier); // Will override temp!
1263*f5c631daSSadaf Ebrahimi // __ Pacia1716();
1264*f5c631daSSadaf Ebrahimi //
1265*f5c631daSSadaf Ebrahimi // To work around this issue, you must exclude x16 and x17 from the scratch
1266*f5c631daSSadaf Ebrahimi // register list. You may need to replace them with other registers:
1267*f5c631daSSadaf Ebrahimi //
1268*f5c631daSSadaf Ebrahimi // UseScratchRegisterScope temps(&masm);
1269*f5c631daSSadaf Ebrahimi // temps.Exclude(x16, x17);
1270*f5c631daSSadaf Ebrahimi // temps.Include(x10, x11);
1271*f5c631daSSadaf Ebrahimi // __ Mov(x17, ptr);
1272*f5c631daSSadaf Ebrahimi // __ Mov(x16, modifier);
1273*f5c631daSSadaf Ebrahimi // __ Pacia1716();
1274*f5c631daSSadaf Ebrahimi void Pacia1716() {
1275*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1276*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!GetScratchRegisterList()->IncludesAliasOf(x16));
1277*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!GetScratchRegisterList()->IncludesAliasOf(x17));
1278*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1279*f5c631daSSadaf Ebrahimi pacia1716();
1280*f5c631daSSadaf Ebrahimi }
Pacib1716()1281*f5c631daSSadaf Ebrahimi void Pacib1716() {
1282*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1283*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!GetScratchRegisterList()->IncludesAliasOf(x16));
1284*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!GetScratchRegisterList()->IncludesAliasOf(x17));
1285*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1286*f5c631daSSadaf Ebrahimi pacib1716();
1287*f5c631daSSadaf Ebrahimi }
Autia1716()1288*f5c631daSSadaf Ebrahimi void Autia1716() {
1289*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1290*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!GetScratchRegisterList()->IncludesAliasOf(x16));
1291*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!GetScratchRegisterList()->IncludesAliasOf(x17));
1292*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1293*f5c631daSSadaf Ebrahimi autia1716();
1294*f5c631daSSadaf Ebrahimi }
Autib1716()1295*f5c631daSSadaf Ebrahimi void Autib1716() {
1296*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1297*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!GetScratchRegisterList()->IncludesAliasOf(x16));
1298*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!GetScratchRegisterList()->IncludesAliasOf(x17));
1299*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1300*f5c631daSSadaf Ebrahimi autib1716();
1301*f5c631daSSadaf Ebrahimi }
Xpaclri()1302*f5c631daSSadaf Ebrahimi void Xpaclri() {
1303*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1304*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1305*f5c631daSSadaf Ebrahimi xpaclri();
1306*f5c631daSSadaf Ebrahimi }
Clrex()1307*f5c631daSSadaf Ebrahimi void Clrex() {
1308*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1309*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1310*f5c631daSSadaf Ebrahimi clrex();
1311*f5c631daSSadaf Ebrahimi }
Cls(const Register & rd,const Register & rn)1312*f5c631daSSadaf Ebrahimi void Cls(const Register& rd, const Register& rn) {
1313*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1314*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1315*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
1316*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1317*f5c631daSSadaf Ebrahimi cls(rd, rn);
1318*f5c631daSSadaf Ebrahimi }
Clz(const Register & rd,const Register & rn)1319*f5c631daSSadaf Ebrahimi void Clz(const Register& rd, const Register& rn) {
1320*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1321*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1322*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
1323*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1324*f5c631daSSadaf Ebrahimi clz(rd, rn);
1325*f5c631daSSadaf Ebrahimi }
Cneg(const Register & rd,const Register & rn,Condition cond)1326*f5c631daSSadaf Ebrahimi void Cneg(const Register& rd, const Register& rn, Condition cond) {
1327*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1328*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1329*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
1330*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1331*f5c631daSSadaf Ebrahimi cneg(rd, rn, cond);
1332*f5c631daSSadaf Ebrahimi }
Esb()1333*f5c631daSSadaf Ebrahimi void Esb() {
1334*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1335*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1336*f5c631daSSadaf Ebrahimi esb();
1337*f5c631daSSadaf Ebrahimi }
Csdb()1338*f5c631daSSadaf Ebrahimi void Csdb() {
1339*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1340*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1341*f5c631daSSadaf Ebrahimi csdb();
1342*f5c631daSSadaf Ebrahimi }
Cset(const Register & rd,Condition cond)1343*f5c631daSSadaf Ebrahimi void Cset(const Register& rd, Condition cond) {
1344*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1345*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1346*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1347*f5c631daSSadaf Ebrahimi cset(rd, cond);
1348*f5c631daSSadaf Ebrahimi }
Csetm(const Register & rd,Condition cond)1349*f5c631daSSadaf Ebrahimi void Csetm(const Register& rd, Condition cond) {
1350*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1351*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1352*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1353*f5c631daSSadaf Ebrahimi csetm(rd, cond);
1354*f5c631daSSadaf Ebrahimi }
Csinc(const Register & rd,const Register & rn,const Register & rm,Condition cond)1355*f5c631daSSadaf Ebrahimi void Csinc(const Register& rd,
1356*f5c631daSSadaf Ebrahimi const Register& rn,
1357*f5c631daSSadaf Ebrahimi const Register& rm,
1358*f5c631daSSadaf Ebrahimi Condition cond) {
1359*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1360*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1361*f5c631daSSadaf Ebrahimi VIXL_ASSERT((cond != al) && (cond != nv));
1362*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1363*f5c631daSSadaf Ebrahimi csinc(rd, rn, rm, cond);
1364*f5c631daSSadaf Ebrahimi }
Csinv(const Register & rd,const Register & rn,const Register & rm,Condition cond)1365*f5c631daSSadaf Ebrahimi void Csinv(const Register& rd,
1366*f5c631daSSadaf Ebrahimi const Register& rn,
1367*f5c631daSSadaf Ebrahimi const Register& rm,
1368*f5c631daSSadaf Ebrahimi Condition cond) {
1369*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1370*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1371*f5c631daSSadaf Ebrahimi VIXL_ASSERT((cond != al) && (cond != nv));
1372*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1373*f5c631daSSadaf Ebrahimi csinv(rd, rn, rm, cond);
1374*f5c631daSSadaf Ebrahimi }
Csneg(const Register & rd,const Register & rn,const Register & rm,Condition cond)1375*f5c631daSSadaf Ebrahimi void Csneg(const Register& rd,
1376*f5c631daSSadaf Ebrahimi const Register& rn,
1377*f5c631daSSadaf Ebrahimi const Register& rm,
1378*f5c631daSSadaf Ebrahimi Condition cond) {
1379*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1380*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1381*f5c631daSSadaf Ebrahimi VIXL_ASSERT((cond != al) && (cond != nv));
1382*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1383*f5c631daSSadaf Ebrahimi csneg(rd, rn, rm, cond);
1384*f5c631daSSadaf Ebrahimi }
Dmb(BarrierDomain domain,BarrierType type)1385*f5c631daSSadaf Ebrahimi void Dmb(BarrierDomain domain, BarrierType type) {
1386*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1387*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1388*f5c631daSSadaf Ebrahimi dmb(domain, type);
1389*f5c631daSSadaf Ebrahimi }
Dsb(BarrierDomain domain,BarrierType type)1390*f5c631daSSadaf Ebrahimi void Dsb(BarrierDomain domain, BarrierType type) {
1391*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1392*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1393*f5c631daSSadaf Ebrahimi dsb(domain, type);
1394*f5c631daSSadaf Ebrahimi }
Extr(const Register & rd,const Register & rn,const Register & rm,unsigned lsb)1395*f5c631daSSadaf Ebrahimi void Extr(const Register& rd,
1396*f5c631daSSadaf Ebrahimi const Register& rn,
1397*f5c631daSSadaf Ebrahimi const Register& rm,
1398*f5c631daSSadaf Ebrahimi unsigned lsb) {
1399*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1400*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1401*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
1402*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rm.IsZero());
1403*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1404*f5c631daSSadaf Ebrahimi extr(rd, rn, rm, lsb);
1405*f5c631daSSadaf Ebrahimi }
Fadd(const VRegister & vd,const VRegister & vn,const VRegister & vm)1406*f5c631daSSadaf Ebrahimi void Fadd(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
1407*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1408*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1409*f5c631daSSadaf Ebrahimi fadd(vd, vn, vm);
1410*f5c631daSSadaf Ebrahimi }
1411*f5c631daSSadaf Ebrahimi void Fccmp(const VRegister& vn,
1412*f5c631daSSadaf Ebrahimi const VRegister& vm,
1413*f5c631daSSadaf Ebrahimi StatusFlags nzcv,
1414*f5c631daSSadaf Ebrahimi Condition cond,
1415*f5c631daSSadaf Ebrahimi FPTrapFlags trap = DisableTrap) {
1416*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1417*f5c631daSSadaf Ebrahimi VIXL_ASSERT((cond != al) && (cond != nv));
1418*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1419*f5c631daSSadaf Ebrahimi FPCCompareMacro(vn, vm, nzcv, cond, trap);
1420*f5c631daSSadaf Ebrahimi }
Fccmpe(const VRegister & vn,const VRegister & vm,StatusFlags nzcv,Condition cond)1421*f5c631daSSadaf Ebrahimi void Fccmpe(const VRegister& vn,
1422*f5c631daSSadaf Ebrahimi const VRegister& vm,
1423*f5c631daSSadaf Ebrahimi StatusFlags nzcv,
1424*f5c631daSSadaf Ebrahimi Condition cond) {
1425*f5c631daSSadaf Ebrahimi Fccmp(vn, vm, nzcv, cond, EnableTrap);
1426*f5c631daSSadaf Ebrahimi }
1427*f5c631daSSadaf Ebrahimi void Fcmp(const VRegister& vn,
1428*f5c631daSSadaf Ebrahimi const VRegister& vm,
1429*f5c631daSSadaf Ebrahimi FPTrapFlags trap = DisableTrap) {
1430*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1431*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1432*f5c631daSSadaf Ebrahimi FPCompareMacro(vn, vm, trap);
1433*f5c631daSSadaf Ebrahimi }
1434*f5c631daSSadaf Ebrahimi void Fcmp(const VRegister& vn, double value, FPTrapFlags trap = DisableTrap);
1435*f5c631daSSadaf Ebrahimi void Fcmpe(const VRegister& vn, double value);
Fcmpe(const VRegister & vn,const VRegister & vm)1436*f5c631daSSadaf Ebrahimi void Fcmpe(const VRegister& vn, const VRegister& vm) {
1437*f5c631daSSadaf Ebrahimi Fcmp(vn, vm, EnableTrap);
1438*f5c631daSSadaf Ebrahimi }
Fcsel(const VRegister & vd,const VRegister & vn,const VRegister & vm,Condition cond)1439*f5c631daSSadaf Ebrahimi void Fcsel(const VRegister& vd,
1440*f5c631daSSadaf Ebrahimi const VRegister& vn,
1441*f5c631daSSadaf Ebrahimi const VRegister& vm,
1442*f5c631daSSadaf Ebrahimi Condition cond) {
1443*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1444*f5c631daSSadaf Ebrahimi VIXL_ASSERT((cond != al) && (cond != nv));
1445*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1446*f5c631daSSadaf Ebrahimi fcsel(vd, vn, vm, cond);
1447*f5c631daSSadaf Ebrahimi }
Fcvt(const VRegister & vd,const VRegister & vn)1448*f5c631daSSadaf Ebrahimi void Fcvt(const VRegister& vd, const VRegister& vn) {
1449*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1450*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1451*f5c631daSSadaf Ebrahimi fcvt(vd, vn);
1452*f5c631daSSadaf Ebrahimi }
Fcvtl(const VRegister & vd,const VRegister & vn)1453*f5c631daSSadaf Ebrahimi void Fcvtl(const VRegister& vd, const VRegister& vn) {
1454*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1455*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1456*f5c631daSSadaf Ebrahimi fcvtl(vd, vn);
1457*f5c631daSSadaf Ebrahimi }
Fcvtl2(const VRegister & vd,const VRegister & vn)1458*f5c631daSSadaf Ebrahimi void Fcvtl2(const VRegister& vd, const VRegister& vn) {
1459*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1460*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1461*f5c631daSSadaf Ebrahimi fcvtl2(vd, vn);
1462*f5c631daSSadaf Ebrahimi }
Fcvtn(const VRegister & vd,const VRegister & vn)1463*f5c631daSSadaf Ebrahimi void Fcvtn(const VRegister& vd, const VRegister& vn) {
1464*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1465*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1466*f5c631daSSadaf Ebrahimi fcvtn(vd, vn);
1467*f5c631daSSadaf Ebrahimi }
Fcvtn2(const VRegister & vd,const VRegister & vn)1468*f5c631daSSadaf Ebrahimi void Fcvtn2(const VRegister& vd, const VRegister& vn) {
1469*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1470*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1471*f5c631daSSadaf Ebrahimi fcvtn2(vd, vn);
1472*f5c631daSSadaf Ebrahimi }
Fcvtxn(const VRegister & vd,const VRegister & vn)1473*f5c631daSSadaf Ebrahimi void Fcvtxn(const VRegister& vd, const VRegister& vn) {
1474*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1475*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1476*f5c631daSSadaf Ebrahimi fcvtxn(vd, vn);
1477*f5c631daSSadaf Ebrahimi }
Fcvtxn2(const VRegister & vd,const VRegister & vn)1478*f5c631daSSadaf Ebrahimi void Fcvtxn2(const VRegister& vd, const VRegister& vn) {
1479*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1480*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1481*f5c631daSSadaf Ebrahimi fcvtxn2(vd, vn);
1482*f5c631daSSadaf Ebrahimi }
Fcvtas(const Register & rd,const VRegister & vn)1483*f5c631daSSadaf Ebrahimi void Fcvtas(const Register& rd, const VRegister& vn) {
1484*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1485*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1486*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1487*f5c631daSSadaf Ebrahimi fcvtas(rd, vn);
1488*f5c631daSSadaf Ebrahimi }
Fcvtau(const Register & rd,const VRegister & vn)1489*f5c631daSSadaf Ebrahimi void Fcvtau(const Register& rd, const VRegister& vn) {
1490*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1491*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1492*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1493*f5c631daSSadaf Ebrahimi fcvtau(rd, vn);
1494*f5c631daSSadaf Ebrahimi }
Fcvtms(const Register & rd,const VRegister & vn)1495*f5c631daSSadaf Ebrahimi void Fcvtms(const Register& rd, const VRegister& vn) {
1496*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1497*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1498*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1499*f5c631daSSadaf Ebrahimi fcvtms(rd, vn);
1500*f5c631daSSadaf Ebrahimi }
Fcvtmu(const Register & rd,const VRegister & vn)1501*f5c631daSSadaf Ebrahimi void Fcvtmu(const Register& rd, const VRegister& vn) {
1502*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1503*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1504*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1505*f5c631daSSadaf Ebrahimi fcvtmu(rd, vn);
1506*f5c631daSSadaf Ebrahimi }
Fcvtns(const Register & rd,const VRegister & vn)1507*f5c631daSSadaf Ebrahimi void Fcvtns(const Register& rd, const VRegister& vn) {
1508*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1509*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1510*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1511*f5c631daSSadaf Ebrahimi fcvtns(rd, vn);
1512*f5c631daSSadaf Ebrahimi }
Fcvtnu(const Register & rd,const VRegister & vn)1513*f5c631daSSadaf Ebrahimi void Fcvtnu(const Register& rd, const VRegister& vn) {
1514*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1515*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1516*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1517*f5c631daSSadaf Ebrahimi fcvtnu(rd, vn);
1518*f5c631daSSadaf Ebrahimi }
Fcvtps(const Register & rd,const VRegister & vn)1519*f5c631daSSadaf Ebrahimi void Fcvtps(const Register& rd, const VRegister& vn) {
1520*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1521*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1522*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1523*f5c631daSSadaf Ebrahimi fcvtps(rd, vn);
1524*f5c631daSSadaf Ebrahimi }
Fcvtpu(const Register & rd,const VRegister & vn)1525*f5c631daSSadaf Ebrahimi void Fcvtpu(const Register& rd, const VRegister& vn) {
1526*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1527*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1528*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1529*f5c631daSSadaf Ebrahimi fcvtpu(rd, vn);
1530*f5c631daSSadaf Ebrahimi }
1531*f5c631daSSadaf Ebrahimi void Fcvtzs(const Register& rd, const VRegister& vn, int fbits = 0) {
1532*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1533*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1534*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1535*f5c631daSSadaf Ebrahimi fcvtzs(rd, vn, fbits);
1536*f5c631daSSadaf Ebrahimi }
Fjcvtzs(const Register & rd,const VRegister & vn)1537*f5c631daSSadaf Ebrahimi void Fjcvtzs(const Register& rd, const VRegister& vn) {
1538*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1539*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1540*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1541*f5c631daSSadaf Ebrahimi fjcvtzs(rd, vn);
1542*f5c631daSSadaf Ebrahimi }
1543*f5c631daSSadaf Ebrahimi void Fcvtzu(const Register& rd, const VRegister& vn, int fbits = 0) {
1544*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1545*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1546*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1547*f5c631daSSadaf Ebrahimi fcvtzu(rd, vn, fbits);
1548*f5c631daSSadaf Ebrahimi }
Fdiv(const VRegister & vd,const VRegister & vn,const VRegister & vm)1549*f5c631daSSadaf Ebrahimi void Fdiv(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
1550*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1551*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1552*f5c631daSSadaf Ebrahimi fdiv(vd, vn, vm);
1553*f5c631daSSadaf Ebrahimi }
Fmax(const VRegister & vd,const VRegister & vn,const VRegister & vm)1554*f5c631daSSadaf Ebrahimi void Fmax(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
1555*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1556*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1557*f5c631daSSadaf Ebrahimi fmax(vd, vn, vm);
1558*f5c631daSSadaf Ebrahimi }
Fmaxnm(const VRegister & vd,const VRegister & vn,const VRegister & vm)1559*f5c631daSSadaf Ebrahimi void Fmaxnm(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
1560*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1561*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1562*f5c631daSSadaf Ebrahimi fmaxnm(vd, vn, vm);
1563*f5c631daSSadaf Ebrahimi }
Fmin(const VRegister & vd,const VRegister & vn,const VRegister & vm)1564*f5c631daSSadaf Ebrahimi void Fmin(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
1565*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1566*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1567*f5c631daSSadaf Ebrahimi fmin(vd, vn, vm);
1568*f5c631daSSadaf Ebrahimi }
Fminnm(const VRegister & vd,const VRegister & vn,const VRegister & vm)1569*f5c631daSSadaf Ebrahimi void Fminnm(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
1570*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1571*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1572*f5c631daSSadaf Ebrahimi fminnm(vd, vn, vm);
1573*f5c631daSSadaf Ebrahimi }
Fmov(const VRegister & vd,const VRegister & vn)1574*f5c631daSSadaf Ebrahimi void Fmov(const VRegister& vd, const VRegister& vn) {
1575*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1576*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1577*f5c631daSSadaf Ebrahimi // TODO: Use DiscardMoveMode to allow this move to be elided if vd.Is(vn).
1578*f5c631daSSadaf Ebrahimi fmov(vd, vn);
1579*f5c631daSSadaf Ebrahimi }
Fmov(const VRegister & vd,const Register & rn)1580*f5c631daSSadaf Ebrahimi void Fmov(const VRegister& vd, const Register& rn) {
1581*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1582*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
1583*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1584*f5c631daSSadaf Ebrahimi fmov(vd, rn);
1585*f5c631daSSadaf Ebrahimi }
Fmov(const VRegister & vd,int index,const Register & rn)1586*f5c631daSSadaf Ebrahimi void Fmov(const VRegister& vd, int index, const Register& rn) {
1587*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1588*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1589*f5c631daSSadaf Ebrahimi if (vd.Is1D() && (index == 0)) {
1590*f5c631daSSadaf Ebrahimi mov(vd, index, rn);
1591*f5c631daSSadaf Ebrahimi } else {
1592*f5c631daSSadaf Ebrahimi fmov(vd, index, rn);
1593*f5c631daSSadaf Ebrahimi }
1594*f5c631daSSadaf Ebrahimi }
Fmov(const Register & rd,const VRegister & vn,int index)1595*f5c631daSSadaf Ebrahimi void Fmov(const Register& rd, const VRegister& vn, int index) {
1596*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1597*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1598*f5c631daSSadaf Ebrahimi if (vn.Is1D() && (index == 0)) {
1599*f5c631daSSadaf Ebrahimi mov(rd, vn, index);
1600*f5c631daSSadaf Ebrahimi } else {
1601*f5c631daSSadaf Ebrahimi fmov(rd, vn, index);
1602*f5c631daSSadaf Ebrahimi }
1603*f5c631daSSadaf Ebrahimi }
1604*f5c631daSSadaf Ebrahimi
1605*f5c631daSSadaf Ebrahimi // Provide explicit double and float interfaces for FP immediate moves, rather
1606*f5c631daSSadaf Ebrahimi // than relying on implicit C++ casts. This allows signalling NaNs to be
1607*f5c631daSSadaf Ebrahimi // preserved when the immediate matches the format of vd. Most systems convert
1608*f5c631daSSadaf Ebrahimi // signalling NaNs to quiet NaNs when converting between float and double.
1609*f5c631daSSadaf Ebrahimi void Fmov(VRegister vd, double imm);
1610*f5c631daSSadaf Ebrahimi void Fmov(VRegister vd, float imm);
1611*f5c631daSSadaf Ebrahimi void Fmov(VRegister vd, const Float16 imm);
1612*f5c631daSSadaf Ebrahimi // Provide a template to allow other types to be converted automatically.
1613*f5c631daSSadaf Ebrahimi template <typename T>
Fmov(VRegister vd,T imm)1614*f5c631daSSadaf Ebrahimi void Fmov(VRegister vd, T imm) {
1615*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1616*f5c631daSSadaf Ebrahimi Fmov(vd, static_cast<double>(imm));
1617*f5c631daSSadaf Ebrahimi }
Fmov(Register rd,VRegister vn)1618*f5c631daSSadaf Ebrahimi void Fmov(Register rd, VRegister vn) {
1619*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1620*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
1621*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1622*f5c631daSSadaf Ebrahimi fmov(rd, vn);
1623*f5c631daSSadaf Ebrahimi }
Fmul(const VRegister & vd,const VRegister & vn,const VRegister & vm)1624*f5c631daSSadaf Ebrahimi void Fmul(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
1625*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1626*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1627*f5c631daSSadaf Ebrahimi fmul(vd, vn, vm);
1628*f5c631daSSadaf Ebrahimi }
Fnmul(const VRegister & vd,const VRegister & vn,const VRegister & vm)1629*f5c631daSSadaf Ebrahimi void Fnmul(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
1630*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1631*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1632*f5c631daSSadaf Ebrahimi fnmul(vd, vn, vm);
1633*f5c631daSSadaf Ebrahimi }
Fmadd(const VRegister & vd,const VRegister & vn,const VRegister & vm,const VRegister & va)1634*f5c631daSSadaf Ebrahimi void Fmadd(const VRegister& vd,
1635*f5c631daSSadaf Ebrahimi const VRegister& vn,
1636*f5c631daSSadaf Ebrahimi const VRegister& vm,
1637*f5c631daSSadaf Ebrahimi const VRegister& va) {
1638*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1639*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1640*f5c631daSSadaf Ebrahimi fmadd(vd, vn, vm, va);
1641*f5c631daSSadaf Ebrahimi }
Fmsub(const VRegister & vd,const VRegister & vn,const VRegister & vm,const VRegister & va)1642*f5c631daSSadaf Ebrahimi void Fmsub(const VRegister& vd,
1643*f5c631daSSadaf Ebrahimi const VRegister& vn,
1644*f5c631daSSadaf Ebrahimi const VRegister& vm,
1645*f5c631daSSadaf Ebrahimi const VRegister& va) {
1646*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1647*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1648*f5c631daSSadaf Ebrahimi fmsub(vd, vn, vm, va);
1649*f5c631daSSadaf Ebrahimi }
Fnmadd(const VRegister & vd,const VRegister & vn,const VRegister & vm,const VRegister & va)1650*f5c631daSSadaf Ebrahimi void Fnmadd(const VRegister& vd,
1651*f5c631daSSadaf Ebrahimi const VRegister& vn,
1652*f5c631daSSadaf Ebrahimi const VRegister& vm,
1653*f5c631daSSadaf Ebrahimi const VRegister& va) {
1654*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1655*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1656*f5c631daSSadaf Ebrahimi fnmadd(vd, vn, vm, va);
1657*f5c631daSSadaf Ebrahimi }
Fnmsub(const VRegister & vd,const VRegister & vn,const VRegister & vm,const VRegister & va)1658*f5c631daSSadaf Ebrahimi void Fnmsub(const VRegister& vd,
1659*f5c631daSSadaf Ebrahimi const VRegister& vn,
1660*f5c631daSSadaf Ebrahimi const VRegister& vm,
1661*f5c631daSSadaf Ebrahimi const VRegister& va) {
1662*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1663*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1664*f5c631daSSadaf Ebrahimi fnmsub(vd, vn, vm, va);
1665*f5c631daSSadaf Ebrahimi }
Fsub(const VRegister & vd,const VRegister & vn,const VRegister & vm)1666*f5c631daSSadaf Ebrahimi void Fsub(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
1667*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1668*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1669*f5c631daSSadaf Ebrahimi fsub(vd, vn, vm);
1670*f5c631daSSadaf Ebrahimi }
Hint(SystemHint code)1671*f5c631daSSadaf Ebrahimi void Hint(SystemHint code) {
1672*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1673*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1674*f5c631daSSadaf Ebrahimi hint(code);
1675*f5c631daSSadaf Ebrahimi }
Hint(int imm7)1676*f5c631daSSadaf Ebrahimi void Hint(int imm7) {
1677*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1678*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1679*f5c631daSSadaf Ebrahimi hint(imm7);
1680*f5c631daSSadaf Ebrahimi }
Hlt(int code)1681*f5c631daSSadaf Ebrahimi void Hlt(int code) {
1682*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1683*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1684*f5c631daSSadaf Ebrahimi hlt(code);
1685*f5c631daSSadaf Ebrahimi }
Isb()1686*f5c631daSSadaf Ebrahimi void Isb() {
1687*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1688*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1689*f5c631daSSadaf Ebrahimi isb();
1690*f5c631daSSadaf Ebrahimi }
Ldar(const Register & rt,const MemOperand & src)1691*f5c631daSSadaf Ebrahimi void Ldar(const Register& rt, const MemOperand& src) {
1692*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1693*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1694*f5c631daSSadaf Ebrahimi ldar(rt, src);
1695*f5c631daSSadaf Ebrahimi }
Ldarb(const Register & rt,const MemOperand & src)1696*f5c631daSSadaf Ebrahimi void Ldarb(const Register& rt, const MemOperand& src) {
1697*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1698*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1699*f5c631daSSadaf Ebrahimi ldarb(rt, src);
1700*f5c631daSSadaf Ebrahimi }
Ldarh(const Register & rt,const MemOperand & src)1701*f5c631daSSadaf Ebrahimi void Ldarh(const Register& rt, const MemOperand& src) {
1702*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1703*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1704*f5c631daSSadaf Ebrahimi ldarh(rt, src);
1705*f5c631daSSadaf Ebrahimi }
Ldlar(const Register & rt,const MemOperand & src)1706*f5c631daSSadaf Ebrahimi void Ldlar(const Register& rt, const MemOperand& src) {
1707*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1708*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1709*f5c631daSSadaf Ebrahimi ldlar(rt, src);
1710*f5c631daSSadaf Ebrahimi }
Ldlarb(const Register & rt,const MemOperand & src)1711*f5c631daSSadaf Ebrahimi void Ldlarb(const Register& rt, const MemOperand& src) {
1712*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1713*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1714*f5c631daSSadaf Ebrahimi ldlarb(rt, src);
1715*f5c631daSSadaf Ebrahimi }
Ldlarh(const Register & rt,const MemOperand & src)1716*f5c631daSSadaf Ebrahimi void Ldlarh(const Register& rt, const MemOperand& src) {
1717*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1718*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1719*f5c631daSSadaf Ebrahimi ldlarh(rt, src);
1720*f5c631daSSadaf Ebrahimi }
Ldaxp(const Register & rt,const Register & rt2,const MemOperand & src)1721*f5c631daSSadaf Ebrahimi void Ldaxp(const Register& rt, const Register& rt2, const MemOperand& src) {
1722*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1723*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rt.Aliases(rt2));
1724*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1725*f5c631daSSadaf Ebrahimi ldaxp(rt, rt2, src);
1726*f5c631daSSadaf Ebrahimi }
Ldaxr(const Register & rt,const MemOperand & src)1727*f5c631daSSadaf Ebrahimi void Ldaxr(const Register& rt, const MemOperand& src) {
1728*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1729*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1730*f5c631daSSadaf Ebrahimi ldaxr(rt, src);
1731*f5c631daSSadaf Ebrahimi }
Ldaxrb(const Register & rt,const MemOperand & src)1732*f5c631daSSadaf Ebrahimi void Ldaxrb(const Register& rt, const MemOperand& src) {
1733*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1734*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1735*f5c631daSSadaf Ebrahimi ldaxrb(rt, src);
1736*f5c631daSSadaf Ebrahimi }
Ldaxrh(const Register & rt,const MemOperand & src)1737*f5c631daSSadaf Ebrahimi void Ldaxrh(const Register& rt, const MemOperand& src) {
1738*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1739*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1740*f5c631daSSadaf Ebrahimi ldaxrh(rt, src);
1741*f5c631daSSadaf Ebrahimi }
1742*f5c631daSSadaf Ebrahimi
1743*f5c631daSSadaf Ebrahimi // clang-format off
1744*f5c631daSSadaf Ebrahimi #define COMPARE_AND_SWAP_SINGLE_MACRO_LIST(V) \
1745*f5c631daSSadaf Ebrahimi V(cas, Cas) \
1746*f5c631daSSadaf Ebrahimi V(casa, Casa) \
1747*f5c631daSSadaf Ebrahimi V(casl, Casl) \
1748*f5c631daSSadaf Ebrahimi V(casal, Casal) \
1749*f5c631daSSadaf Ebrahimi V(casb, Casb) \
1750*f5c631daSSadaf Ebrahimi V(casab, Casab) \
1751*f5c631daSSadaf Ebrahimi V(caslb, Caslb) \
1752*f5c631daSSadaf Ebrahimi V(casalb, Casalb) \
1753*f5c631daSSadaf Ebrahimi V(cash, Cash) \
1754*f5c631daSSadaf Ebrahimi V(casah, Casah) \
1755*f5c631daSSadaf Ebrahimi V(caslh, Caslh) \
1756*f5c631daSSadaf Ebrahimi V(casalh, Casalh)
1757*f5c631daSSadaf Ebrahimi // clang-format on
1758*f5c631daSSadaf Ebrahimi
1759*f5c631daSSadaf Ebrahimi #define DEFINE_MACRO_ASM_FUNC(ASM, MASM) \
1760*f5c631daSSadaf Ebrahimi void MASM(const Register& rs, const Register& rt, const MemOperand& src) { \
1761*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_); \
1762*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this); \
1763*f5c631daSSadaf Ebrahimi ASM(rs, rt, src); \
1764*f5c631daSSadaf Ebrahimi }
1765*f5c631daSSadaf Ebrahimi COMPARE_AND_SWAP_SINGLE_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
1766*f5c631daSSadaf Ebrahimi #undef DEFINE_MACRO_ASM_FUNC
1767*f5c631daSSadaf Ebrahimi
1768*f5c631daSSadaf Ebrahimi
1769*f5c631daSSadaf Ebrahimi // clang-format off
1770*f5c631daSSadaf Ebrahimi #define COMPARE_AND_SWAP_PAIR_MACRO_LIST(V) \
1771*f5c631daSSadaf Ebrahimi V(casp, Casp) \
1772*f5c631daSSadaf Ebrahimi V(caspa, Caspa) \
1773*f5c631daSSadaf Ebrahimi V(caspl, Caspl) \
1774*f5c631daSSadaf Ebrahimi V(caspal, Caspal)
1775*f5c631daSSadaf Ebrahimi // clang-format on
1776*f5c631daSSadaf Ebrahimi
1777*f5c631daSSadaf Ebrahimi #define DEFINE_MACRO_ASM_FUNC(ASM, MASM) \
1778*f5c631daSSadaf Ebrahimi void MASM(const Register& rs, \
1779*f5c631daSSadaf Ebrahimi const Register& rs2, \
1780*f5c631daSSadaf Ebrahimi const Register& rt, \
1781*f5c631daSSadaf Ebrahimi const Register& rt2, \
1782*f5c631daSSadaf Ebrahimi const MemOperand& src) { \
1783*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_); \
1784*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this); \
1785*f5c631daSSadaf Ebrahimi ASM(rs, rs2, rt, rt2, src); \
1786*f5c631daSSadaf Ebrahimi }
COMPARE_AND_SWAP_PAIR_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)1787*f5c631daSSadaf Ebrahimi COMPARE_AND_SWAP_PAIR_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
1788*f5c631daSSadaf Ebrahimi #undef DEFINE_MACRO_ASM_FUNC
1789*f5c631daSSadaf Ebrahimi
1790*f5c631daSSadaf Ebrahimi // These macros generate all the variations of the atomic memory operations,
1791*f5c631daSSadaf Ebrahimi // e.g. ldadd, ldadda, ldaddb, staddl, etc.
1792*f5c631daSSadaf Ebrahimi
1793*f5c631daSSadaf Ebrahimi // clang-format off
1794*f5c631daSSadaf Ebrahimi #define ATOMIC_MEMORY_SIMPLE_MACRO_LIST(V, DEF, MASM_PRE, ASM_PRE) \
1795*f5c631daSSadaf Ebrahimi V(DEF, MASM_PRE##add, ASM_PRE##add) \
1796*f5c631daSSadaf Ebrahimi V(DEF, MASM_PRE##clr, ASM_PRE##clr) \
1797*f5c631daSSadaf Ebrahimi V(DEF, MASM_PRE##eor, ASM_PRE##eor) \
1798*f5c631daSSadaf Ebrahimi V(DEF, MASM_PRE##set, ASM_PRE##set) \
1799*f5c631daSSadaf Ebrahimi V(DEF, MASM_PRE##smax, ASM_PRE##smax) \
1800*f5c631daSSadaf Ebrahimi V(DEF, MASM_PRE##smin, ASM_PRE##smin) \
1801*f5c631daSSadaf Ebrahimi V(DEF, MASM_PRE##umax, ASM_PRE##umax) \
1802*f5c631daSSadaf Ebrahimi V(DEF, MASM_PRE##umin, ASM_PRE##umin)
1803*f5c631daSSadaf Ebrahimi
1804*f5c631daSSadaf Ebrahimi #define ATOMIC_MEMORY_STORE_MACRO_MODES(V, MASM, ASM) \
1805*f5c631daSSadaf Ebrahimi V(MASM, ASM) \
1806*f5c631daSSadaf Ebrahimi V(MASM##l, ASM##l) \
1807*f5c631daSSadaf Ebrahimi V(MASM##b, ASM##b) \
1808*f5c631daSSadaf Ebrahimi V(MASM##lb, ASM##lb) \
1809*f5c631daSSadaf Ebrahimi V(MASM##h, ASM##h) \
1810*f5c631daSSadaf Ebrahimi V(MASM##lh, ASM##lh)
1811*f5c631daSSadaf Ebrahimi
1812*f5c631daSSadaf Ebrahimi #define ATOMIC_MEMORY_LOAD_MACRO_MODES(V, MASM, ASM) \
1813*f5c631daSSadaf Ebrahimi ATOMIC_MEMORY_STORE_MACRO_MODES(V, MASM, ASM) \
1814*f5c631daSSadaf Ebrahimi V(MASM##a, ASM##a) \
1815*f5c631daSSadaf Ebrahimi V(MASM##al, ASM##al) \
1816*f5c631daSSadaf Ebrahimi V(MASM##ab, ASM##ab) \
1817*f5c631daSSadaf Ebrahimi V(MASM##alb, ASM##alb) \
1818*f5c631daSSadaf Ebrahimi V(MASM##ah, ASM##ah) \
1819*f5c631daSSadaf Ebrahimi V(MASM##alh, ASM##alh)
1820*f5c631daSSadaf Ebrahimi // clang-format on
1821*f5c631daSSadaf Ebrahimi
1822*f5c631daSSadaf Ebrahimi #define DEFINE_MACRO_LOAD_ASM_FUNC(MASM, ASM) \
1823*f5c631daSSadaf Ebrahimi void MASM(const Register& rs, const Register& rt, const MemOperand& src) { \
1824*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_); \
1825*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this); \
1826*f5c631daSSadaf Ebrahimi ASM(rs, rt, src); \
1827*f5c631daSSadaf Ebrahimi }
1828*f5c631daSSadaf Ebrahimi #define DEFINE_MACRO_STORE_ASM_FUNC(MASM, ASM) \
1829*f5c631daSSadaf Ebrahimi void MASM(const Register& rs, const MemOperand& src) { \
1830*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_); \
1831*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this); \
1832*f5c631daSSadaf Ebrahimi ASM(rs, src); \
1833*f5c631daSSadaf Ebrahimi }
1834*f5c631daSSadaf Ebrahimi
1835*f5c631daSSadaf Ebrahimi ATOMIC_MEMORY_SIMPLE_MACRO_LIST(ATOMIC_MEMORY_LOAD_MACRO_MODES,
1836*f5c631daSSadaf Ebrahimi DEFINE_MACRO_LOAD_ASM_FUNC,
1837*f5c631daSSadaf Ebrahimi Ld,
1838*f5c631daSSadaf Ebrahimi ld)
1839*f5c631daSSadaf Ebrahimi ATOMIC_MEMORY_SIMPLE_MACRO_LIST(ATOMIC_MEMORY_STORE_MACRO_MODES,
1840*f5c631daSSadaf Ebrahimi DEFINE_MACRO_STORE_ASM_FUNC,
1841*f5c631daSSadaf Ebrahimi St,
1842*f5c631daSSadaf Ebrahimi st)
1843*f5c631daSSadaf Ebrahimi
1844*f5c631daSSadaf Ebrahimi #define DEFINE_MACRO_SWP_ASM_FUNC(MASM, ASM) \
1845*f5c631daSSadaf Ebrahimi void MASM(const Register& rs, const Register& rt, const MemOperand& src) { \
1846*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_); \
1847*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this); \
1848*f5c631daSSadaf Ebrahimi ASM(rs, rt, src); \
1849*f5c631daSSadaf Ebrahimi }
1850*f5c631daSSadaf Ebrahimi
1851*f5c631daSSadaf Ebrahimi ATOMIC_MEMORY_LOAD_MACRO_MODES(DEFINE_MACRO_SWP_ASM_FUNC, Swp, swp)
1852*f5c631daSSadaf Ebrahimi
1853*f5c631daSSadaf Ebrahimi #undef DEFINE_MACRO_LOAD_ASM_FUNC
1854*f5c631daSSadaf Ebrahimi #undef DEFINE_MACRO_STORE_ASM_FUNC
1855*f5c631daSSadaf Ebrahimi #undef DEFINE_MACRO_SWP_ASM_FUNC
1856*f5c631daSSadaf Ebrahimi
1857*f5c631daSSadaf Ebrahimi void Ldaprb(const Register& rt, const MemOperand& src) {
1858*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1859*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1860*f5c631daSSadaf Ebrahimi VIXL_ASSERT(src.IsImmediateOffset());
1861*f5c631daSSadaf Ebrahimi if (src.GetOffset() == 0) {
1862*f5c631daSSadaf Ebrahimi ldaprb(rt, src);
1863*f5c631daSSadaf Ebrahimi } else {
1864*f5c631daSSadaf Ebrahimi ldapurb(rt, src);
1865*f5c631daSSadaf Ebrahimi }
1866*f5c631daSSadaf Ebrahimi }
1867*f5c631daSSadaf Ebrahimi
Ldapursb(const Register & rt,const MemOperand & src)1868*f5c631daSSadaf Ebrahimi void Ldapursb(const Register& rt, const MemOperand& src) {
1869*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1870*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1871*f5c631daSSadaf Ebrahimi ldapursb(rt, src);
1872*f5c631daSSadaf Ebrahimi }
1873*f5c631daSSadaf Ebrahimi
Ldaprh(const Register & rt,const MemOperand & src)1874*f5c631daSSadaf Ebrahimi void Ldaprh(const Register& rt, const MemOperand& src) {
1875*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1876*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1877*f5c631daSSadaf Ebrahimi VIXL_ASSERT(src.IsImmediateOffset());
1878*f5c631daSSadaf Ebrahimi if (src.GetOffset() == 0) {
1879*f5c631daSSadaf Ebrahimi ldaprh(rt, src);
1880*f5c631daSSadaf Ebrahimi } else {
1881*f5c631daSSadaf Ebrahimi ldapurh(rt, src);
1882*f5c631daSSadaf Ebrahimi }
1883*f5c631daSSadaf Ebrahimi }
1884*f5c631daSSadaf Ebrahimi
Ldapursh(const Register & rt,const MemOperand & src)1885*f5c631daSSadaf Ebrahimi void Ldapursh(const Register& rt, const MemOperand& src) {
1886*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1887*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1888*f5c631daSSadaf Ebrahimi ldapursh(rt, src);
1889*f5c631daSSadaf Ebrahimi }
1890*f5c631daSSadaf Ebrahimi
Ldapr(const Register & rt,const MemOperand & src)1891*f5c631daSSadaf Ebrahimi void Ldapr(const Register& rt, const MemOperand& src) {
1892*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1893*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1894*f5c631daSSadaf Ebrahimi VIXL_ASSERT(src.IsImmediateOffset());
1895*f5c631daSSadaf Ebrahimi if (src.GetOffset() == 0) {
1896*f5c631daSSadaf Ebrahimi ldapr(rt, src);
1897*f5c631daSSadaf Ebrahimi } else {
1898*f5c631daSSadaf Ebrahimi ldapur(rt, src);
1899*f5c631daSSadaf Ebrahimi }
1900*f5c631daSSadaf Ebrahimi }
1901*f5c631daSSadaf Ebrahimi
Ldapursw(const Register & rt,const MemOperand & src)1902*f5c631daSSadaf Ebrahimi void Ldapursw(const Register& rt, const MemOperand& src) {
1903*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1904*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1905*f5c631daSSadaf Ebrahimi ldapursw(rt, src);
1906*f5c631daSSadaf Ebrahimi }
1907*f5c631daSSadaf Ebrahimi
Ldnp(const CPURegister & rt,const CPURegister & rt2,const MemOperand & src)1908*f5c631daSSadaf Ebrahimi void Ldnp(const CPURegister& rt,
1909*f5c631daSSadaf Ebrahimi const CPURegister& rt2,
1910*f5c631daSSadaf Ebrahimi const MemOperand& src) {
1911*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1912*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1913*f5c631daSSadaf Ebrahimi ldnp(rt, rt2, src);
1914*f5c631daSSadaf Ebrahimi }
1915*f5c631daSSadaf Ebrahimi // Provide both double and float interfaces for FP immediate loads, rather
1916*f5c631daSSadaf Ebrahimi // than relying on implicit C++ casts. This allows signalling NaNs to be
1917*f5c631daSSadaf Ebrahimi // preserved when the immediate matches the format of fd. Most systems convert
1918*f5c631daSSadaf Ebrahimi // signalling NaNs to quiet NaNs when converting between float and double.
Ldr(const VRegister & vt,double imm)1919*f5c631daSSadaf Ebrahimi void Ldr(const VRegister& vt, double imm) {
1920*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1921*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1922*f5c631daSSadaf Ebrahimi RawLiteral* literal;
1923*f5c631daSSadaf Ebrahimi if (vt.IsD()) {
1924*f5c631daSSadaf Ebrahimi literal = new Literal<double>(imm,
1925*f5c631daSSadaf Ebrahimi &literal_pool_,
1926*f5c631daSSadaf Ebrahimi RawLiteral::kDeletedOnPlacementByPool);
1927*f5c631daSSadaf Ebrahimi } else {
1928*f5c631daSSadaf Ebrahimi literal = new Literal<float>(static_cast<float>(imm),
1929*f5c631daSSadaf Ebrahimi &literal_pool_,
1930*f5c631daSSadaf Ebrahimi RawLiteral::kDeletedOnPlacementByPool);
1931*f5c631daSSadaf Ebrahimi }
1932*f5c631daSSadaf Ebrahimi ldr(vt, literal);
1933*f5c631daSSadaf Ebrahimi }
Ldr(const VRegister & vt,float imm)1934*f5c631daSSadaf Ebrahimi void Ldr(const VRegister& vt, float imm) {
1935*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1936*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1937*f5c631daSSadaf Ebrahimi RawLiteral* literal;
1938*f5c631daSSadaf Ebrahimi if (vt.IsS()) {
1939*f5c631daSSadaf Ebrahimi literal = new Literal<float>(imm,
1940*f5c631daSSadaf Ebrahimi &literal_pool_,
1941*f5c631daSSadaf Ebrahimi RawLiteral::kDeletedOnPlacementByPool);
1942*f5c631daSSadaf Ebrahimi } else {
1943*f5c631daSSadaf Ebrahimi literal = new Literal<double>(static_cast<double>(imm),
1944*f5c631daSSadaf Ebrahimi &literal_pool_,
1945*f5c631daSSadaf Ebrahimi RawLiteral::kDeletedOnPlacementByPool);
1946*f5c631daSSadaf Ebrahimi }
1947*f5c631daSSadaf Ebrahimi ldr(vt, literal);
1948*f5c631daSSadaf Ebrahimi }
Ldr(const VRegister & vt,uint64_t high64,uint64_t low64)1949*f5c631daSSadaf Ebrahimi void Ldr(const VRegister& vt, uint64_t high64, uint64_t low64) {
1950*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1951*f5c631daSSadaf Ebrahimi VIXL_ASSERT(vt.IsQ());
1952*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1953*f5c631daSSadaf Ebrahimi ldr(vt,
1954*f5c631daSSadaf Ebrahimi new Literal<uint64_t>(high64,
1955*f5c631daSSadaf Ebrahimi low64,
1956*f5c631daSSadaf Ebrahimi &literal_pool_,
1957*f5c631daSSadaf Ebrahimi RawLiteral::kDeletedOnPlacementByPool));
1958*f5c631daSSadaf Ebrahimi }
Ldr(const Register & rt,uint64_t imm)1959*f5c631daSSadaf Ebrahimi void Ldr(const Register& rt, uint64_t imm) {
1960*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1961*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rt.IsZero());
1962*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1963*f5c631daSSadaf Ebrahimi RawLiteral* literal;
1964*f5c631daSSadaf Ebrahimi if (rt.Is64Bits()) {
1965*f5c631daSSadaf Ebrahimi literal = new Literal<uint64_t>(imm,
1966*f5c631daSSadaf Ebrahimi &literal_pool_,
1967*f5c631daSSadaf Ebrahimi RawLiteral::kDeletedOnPlacementByPool);
1968*f5c631daSSadaf Ebrahimi } else {
1969*f5c631daSSadaf Ebrahimi VIXL_ASSERT(rt.Is32Bits());
1970*f5c631daSSadaf Ebrahimi VIXL_ASSERT(IsUint32(imm) || IsInt32(imm));
1971*f5c631daSSadaf Ebrahimi literal = new Literal<uint32_t>(static_cast<uint32_t>(imm),
1972*f5c631daSSadaf Ebrahimi &literal_pool_,
1973*f5c631daSSadaf Ebrahimi RawLiteral::kDeletedOnPlacementByPool);
1974*f5c631daSSadaf Ebrahimi }
1975*f5c631daSSadaf Ebrahimi ldr(rt, literal);
1976*f5c631daSSadaf Ebrahimi }
Ldrsw(const Register & rt,uint32_t imm)1977*f5c631daSSadaf Ebrahimi void Ldrsw(const Register& rt, uint32_t imm) {
1978*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1979*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rt.IsZero());
1980*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1981*f5c631daSSadaf Ebrahimi ldrsw(rt,
1982*f5c631daSSadaf Ebrahimi new Literal<uint32_t>(imm,
1983*f5c631daSSadaf Ebrahimi &literal_pool_,
1984*f5c631daSSadaf Ebrahimi RawLiteral::kDeletedOnPlacementByPool));
1985*f5c631daSSadaf Ebrahimi }
Ldr(const CPURegister & rt,RawLiteral * literal)1986*f5c631daSSadaf Ebrahimi void Ldr(const CPURegister& rt, RawLiteral* literal) {
1987*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1988*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1989*f5c631daSSadaf Ebrahimi ldr(rt, literal);
1990*f5c631daSSadaf Ebrahimi }
Ldrsw(const Register & rt,RawLiteral * literal)1991*f5c631daSSadaf Ebrahimi void Ldrsw(const Register& rt, RawLiteral* literal) {
1992*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1993*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
1994*f5c631daSSadaf Ebrahimi ldrsw(rt, literal);
1995*f5c631daSSadaf Ebrahimi }
Ldxp(const Register & rt,const Register & rt2,const MemOperand & src)1996*f5c631daSSadaf Ebrahimi void Ldxp(const Register& rt, const Register& rt2, const MemOperand& src) {
1997*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
1998*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rt.Aliases(rt2));
1999*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2000*f5c631daSSadaf Ebrahimi ldxp(rt, rt2, src);
2001*f5c631daSSadaf Ebrahimi }
Ldxr(const Register & rt,const MemOperand & src)2002*f5c631daSSadaf Ebrahimi void Ldxr(const Register& rt, const MemOperand& src) {
2003*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2004*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2005*f5c631daSSadaf Ebrahimi ldxr(rt, src);
2006*f5c631daSSadaf Ebrahimi }
Ldxrb(const Register & rt,const MemOperand & src)2007*f5c631daSSadaf Ebrahimi void Ldxrb(const Register& rt, const MemOperand& src) {
2008*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2009*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2010*f5c631daSSadaf Ebrahimi ldxrb(rt, src);
2011*f5c631daSSadaf Ebrahimi }
Ldxrh(const Register & rt,const MemOperand & src)2012*f5c631daSSadaf Ebrahimi void Ldxrh(const Register& rt, const MemOperand& src) {
2013*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2014*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2015*f5c631daSSadaf Ebrahimi ldxrh(rt, src);
2016*f5c631daSSadaf Ebrahimi }
Lsl(const Register & rd,const Register & rn,unsigned shift)2017*f5c631daSSadaf Ebrahimi void Lsl(const Register& rd, const Register& rn, unsigned shift) {
2018*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2019*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2020*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2021*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2022*f5c631daSSadaf Ebrahimi lsl(rd, rn, shift);
2023*f5c631daSSadaf Ebrahimi }
Lsl(const Register & rd,const Register & rn,const Register & rm)2024*f5c631daSSadaf Ebrahimi void Lsl(const Register& rd, const Register& rn, const Register& rm) {
2025*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2026*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2027*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2028*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rm.IsZero());
2029*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2030*f5c631daSSadaf Ebrahimi lslv(rd, rn, rm);
2031*f5c631daSSadaf Ebrahimi }
Lsr(const Register & rd,const Register & rn,unsigned shift)2032*f5c631daSSadaf Ebrahimi void Lsr(const Register& rd, const Register& rn, unsigned shift) {
2033*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2034*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2035*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2036*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2037*f5c631daSSadaf Ebrahimi lsr(rd, rn, shift);
2038*f5c631daSSadaf Ebrahimi }
Lsr(const Register & rd,const Register & rn,const Register & rm)2039*f5c631daSSadaf Ebrahimi void Lsr(const Register& rd, const Register& rn, const Register& rm) {
2040*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2041*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2042*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2043*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rm.IsZero());
2044*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2045*f5c631daSSadaf Ebrahimi lsrv(rd, rn, rm);
2046*f5c631daSSadaf Ebrahimi }
Ldraa(const Register & xt,const MemOperand & src)2047*f5c631daSSadaf Ebrahimi void Ldraa(const Register& xt, const MemOperand& src) {
2048*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2049*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2050*f5c631daSSadaf Ebrahimi ldraa(xt, src);
2051*f5c631daSSadaf Ebrahimi }
Ldrab(const Register & xt,const MemOperand & src)2052*f5c631daSSadaf Ebrahimi void Ldrab(const Register& xt, const MemOperand& src) {
2053*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2054*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2055*f5c631daSSadaf Ebrahimi ldrab(xt, src);
2056*f5c631daSSadaf Ebrahimi }
Madd(const Register & rd,const Register & rn,const Register & rm,const Register & ra)2057*f5c631daSSadaf Ebrahimi void Madd(const Register& rd,
2058*f5c631daSSadaf Ebrahimi const Register& rn,
2059*f5c631daSSadaf Ebrahimi const Register& rm,
2060*f5c631daSSadaf Ebrahimi const Register& ra) {
2061*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2062*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2063*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2064*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rm.IsZero());
2065*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!ra.IsZero());
2066*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2067*f5c631daSSadaf Ebrahimi madd(rd, rn, rm, ra);
2068*f5c631daSSadaf Ebrahimi }
Mneg(const Register & rd,const Register & rn,const Register & rm)2069*f5c631daSSadaf Ebrahimi void Mneg(const Register& rd, const Register& rn, const Register& rm) {
2070*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2071*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2072*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2073*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rm.IsZero());
2074*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2075*f5c631daSSadaf Ebrahimi mneg(rd, rn, rm);
2076*f5c631daSSadaf Ebrahimi }
2077*f5c631daSSadaf Ebrahimi void Mov(const Register& rd,
2078*f5c631daSSadaf Ebrahimi const Register& rn,
2079*f5c631daSSadaf Ebrahimi DiscardMoveMode discard_mode = kDontDiscardForSameWReg) {
2080*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2081*f5c631daSSadaf Ebrahimi // Emit a register move only if the registers are distinct, or if they are
2082*f5c631daSSadaf Ebrahimi // not X registers.
2083*f5c631daSSadaf Ebrahimi //
2084*f5c631daSSadaf Ebrahimi // Note that mov(w0, w0) is not a no-op because it clears the top word of
2085*f5c631daSSadaf Ebrahimi // x0. A flag is provided (kDiscardForSameWReg) if a move between the same W
2086*f5c631daSSadaf Ebrahimi // registers is not required to clear the top word of the X register. In
2087*f5c631daSSadaf Ebrahimi // this case, the instruction is discarded.
2088*f5c631daSSadaf Ebrahimi //
2089*f5c631daSSadaf Ebrahimi // If the sp is an operand, add #0 is emitted, otherwise, orr #0.
2090*f5c631daSSadaf Ebrahimi if (!rd.Is(rn) ||
2091*f5c631daSSadaf Ebrahimi (rd.Is32Bits() && (discard_mode == kDontDiscardForSameWReg))) {
2092*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2093*f5c631daSSadaf Ebrahimi mov(rd, rn);
2094*f5c631daSSadaf Ebrahimi }
2095*f5c631daSSadaf Ebrahimi }
2096*f5c631daSSadaf Ebrahimi void Movk(const Register& rd, uint64_t imm, int shift = -1) {
2097*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2098*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2099*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2100*f5c631daSSadaf Ebrahimi movk(rd, imm, shift);
2101*f5c631daSSadaf Ebrahimi }
Mrs(const Register & rt,SystemRegister sysreg)2102*f5c631daSSadaf Ebrahimi void Mrs(const Register& rt, SystemRegister sysreg) {
2103*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2104*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rt.IsZero());
2105*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2106*f5c631daSSadaf Ebrahimi mrs(rt, sysreg);
2107*f5c631daSSadaf Ebrahimi }
Msr(SystemRegister sysreg,const Register & rt)2108*f5c631daSSadaf Ebrahimi void Msr(SystemRegister sysreg, const Register& rt) {
2109*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2110*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rt.IsZero());
2111*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2112*f5c631daSSadaf Ebrahimi msr(sysreg, rt);
2113*f5c631daSSadaf Ebrahimi }
Cfinv()2114*f5c631daSSadaf Ebrahimi void Cfinv() {
2115*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2116*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2117*f5c631daSSadaf Ebrahimi cfinv();
2118*f5c631daSSadaf Ebrahimi }
Axflag()2119*f5c631daSSadaf Ebrahimi void Axflag() {
2120*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2121*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2122*f5c631daSSadaf Ebrahimi axflag();
2123*f5c631daSSadaf Ebrahimi }
Xaflag()2124*f5c631daSSadaf Ebrahimi void Xaflag() {
2125*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2126*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2127*f5c631daSSadaf Ebrahimi xaflag();
2128*f5c631daSSadaf Ebrahimi }
2129*f5c631daSSadaf Ebrahimi void Sys(int op1, int crn, int crm, int op2, const Register& rt = xzr) {
2130*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2131*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2132*f5c631daSSadaf Ebrahimi sys(op1, crn, crm, op2, rt);
2133*f5c631daSSadaf Ebrahimi }
Dc(DataCacheOp op,const Register & rt)2134*f5c631daSSadaf Ebrahimi void Dc(DataCacheOp op, const Register& rt) {
2135*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2136*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2137*f5c631daSSadaf Ebrahimi dc(op, rt);
2138*f5c631daSSadaf Ebrahimi }
Ic(InstructionCacheOp op,const Register & rt)2139*f5c631daSSadaf Ebrahimi void Ic(InstructionCacheOp op, const Register& rt) {
2140*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2141*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2142*f5c631daSSadaf Ebrahimi ic(op, rt);
2143*f5c631daSSadaf Ebrahimi }
Msub(const Register & rd,const Register & rn,const Register & rm,const Register & ra)2144*f5c631daSSadaf Ebrahimi void Msub(const Register& rd,
2145*f5c631daSSadaf Ebrahimi const Register& rn,
2146*f5c631daSSadaf Ebrahimi const Register& rm,
2147*f5c631daSSadaf Ebrahimi const Register& ra) {
2148*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2149*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2150*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2151*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rm.IsZero());
2152*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!ra.IsZero());
2153*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2154*f5c631daSSadaf Ebrahimi msub(rd, rn, rm, ra);
2155*f5c631daSSadaf Ebrahimi }
Mul(const Register & rd,const Register & rn,const Register & rm)2156*f5c631daSSadaf Ebrahimi void Mul(const Register& rd, const Register& rn, const Register& rm) {
2157*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2158*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2159*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2160*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rm.IsZero());
2161*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2162*f5c631daSSadaf Ebrahimi mul(rd, rn, rm);
2163*f5c631daSSadaf Ebrahimi }
Nop()2164*f5c631daSSadaf Ebrahimi void Nop() {
2165*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2166*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2167*f5c631daSSadaf Ebrahimi nop();
2168*f5c631daSSadaf Ebrahimi }
Rbit(const Register & rd,const Register & rn)2169*f5c631daSSadaf Ebrahimi void Rbit(const Register& rd, const Register& rn) {
2170*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2171*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2172*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2173*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2174*f5c631daSSadaf Ebrahimi rbit(rd, rn);
2175*f5c631daSSadaf Ebrahimi }
2176*f5c631daSSadaf Ebrahimi void Ret(const Register& xn = lr) {
2177*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2178*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!xn.IsZero());
2179*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2180*f5c631daSSadaf Ebrahimi ret(xn);
2181*f5c631daSSadaf Ebrahimi }
Rev(const Register & rd,const Register & rn)2182*f5c631daSSadaf Ebrahimi void Rev(const Register& rd, const Register& rn) {
2183*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2184*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2185*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2186*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2187*f5c631daSSadaf Ebrahimi rev(rd, rn);
2188*f5c631daSSadaf Ebrahimi }
Rev16(const Register & rd,const Register & rn)2189*f5c631daSSadaf Ebrahimi void Rev16(const Register& rd, const Register& rn) {
2190*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2191*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2192*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2193*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2194*f5c631daSSadaf Ebrahimi rev16(rd, rn);
2195*f5c631daSSadaf Ebrahimi }
Rev32(const Register & rd,const Register & rn)2196*f5c631daSSadaf Ebrahimi void Rev32(const Register& rd, const Register& rn) {
2197*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2198*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2199*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2200*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2201*f5c631daSSadaf Ebrahimi rev32(rd, rn);
2202*f5c631daSSadaf Ebrahimi }
Rev64(const Register & rd,const Register & rn)2203*f5c631daSSadaf Ebrahimi void Rev64(const Register& rd, const Register& rn) {
2204*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2205*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2206*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2207*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2208*f5c631daSSadaf Ebrahimi rev64(rd, rn);
2209*f5c631daSSadaf Ebrahimi }
2210*f5c631daSSadaf Ebrahimi
2211*f5c631daSSadaf Ebrahimi #define PAUTH_MASM_VARIATIONS(V) \
2212*f5c631daSSadaf Ebrahimi V(Paci, paci) \
2213*f5c631daSSadaf Ebrahimi V(Pacd, pacd) \
2214*f5c631daSSadaf Ebrahimi V(Auti, auti) \
2215*f5c631daSSadaf Ebrahimi V(Autd, autd)
2216*f5c631daSSadaf Ebrahimi
2217*f5c631daSSadaf Ebrahimi #define DEFINE_MACRO_ASM_FUNCS(MASM_PRE, ASM_PRE) \
2218*f5c631daSSadaf Ebrahimi void MASM_PRE##a(const Register& xd, const Register& xn) { \
2219*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_); \
2220*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this); \
2221*f5c631daSSadaf Ebrahimi ASM_PRE##a(xd, xn); \
2222*f5c631daSSadaf Ebrahimi } \
2223*f5c631daSSadaf Ebrahimi void MASM_PRE##za(const Register& xd) { \
2224*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_); \
2225*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this); \
2226*f5c631daSSadaf Ebrahimi ASM_PRE##za(xd); \
2227*f5c631daSSadaf Ebrahimi } \
2228*f5c631daSSadaf Ebrahimi void MASM_PRE##b(const Register& xd, const Register& xn) { \
2229*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_); \
2230*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this); \
2231*f5c631daSSadaf Ebrahimi ASM_PRE##b(xd, xn); \
2232*f5c631daSSadaf Ebrahimi } \
2233*f5c631daSSadaf Ebrahimi void MASM_PRE##zb(const Register& xd) { \
2234*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_); \
2235*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this); \
2236*f5c631daSSadaf Ebrahimi ASM_PRE##zb(xd); \
2237*f5c631daSSadaf Ebrahimi }
2238*f5c631daSSadaf Ebrahimi
PAUTH_MASM_VARIATIONS(DEFINE_MACRO_ASM_FUNCS)2239*f5c631daSSadaf Ebrahimi PAUTH_MASM_VARIATIONS(DEFINE_MACRO_ASM_FUNCS)
2240*f5c631daSSadaf Ebrahimi #undef DEFINE_MACRO_ASM_FUNCS
2241*f5c631daSSadaf Ebrahimi
2242*f5c631daSSadaf Ebrahimi void Pacga(const Register& xd, const Register& xn, const Register& xm) {
2243*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2244*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2245*f5c631daSSadaf Ebrahimi pacga(xd, xn, xm);
2246*f5c631daSSadaf Ebrahimi }
2247*f5c631daSSadaf Ebrahimi
Xpaci(const Register & xd)2248*f5c631daSSadaf Ebrahimi void Xpaci(const Register& xd) {
2249*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2250*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2251*f5c631daSSadaf Ebrahimi xpaci(xd);
2252*f5c631daSSadaf Ebrahimi }
2253*f5c631daSSadaf Ebrahimi
Xpacd(const Register & xd)2254*f5c631daSSadaf Ebrahimi void Xpacd(const Register& xd) {
2255*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2256*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2257*f5c631daSSadaf Ebrahimi xpacd(xd);
2258*f5c631daSSadaf Ebrahimi }
Ror(const Register & rd,const Register & rs,unsigned shift)2259*f5c631daSSadaf Ebrahimi void Ror(const Register& rd, const Register& rs, unsigned shift) {
2260*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2261*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2262*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rs.IsZero());
2263*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2264*f5c631daSSadaf Ebrahimi ror(rd, rs, shift);
2265*f5c631daSSadaf Ebrahimi }
Ror(const Register & rd,const Register & rn,const Register & rm)2266*f5c631daSSadaf Ebrahimi void Ror(const Register& rd, const Register& rn, const Register& rm) {
2267*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2268*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2269*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2270*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rm.IsZero());
2271*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2272*f5c631daSSadaf Ebrahimi rorv(rd, rn, rm);
2273*f5c631daSSadaf Ebrahimi }
Sbfiz(const Register & rd,const Register & rn,unsigned lsb,unsigned width)2274*f5c631daSSadaf Ebrahimi void Sbfiz(const Register& rd,
2275*f5c631daSSadaf Ebrahimi const Register& rn,
2276*f5c631daSSadaf Ebrahimi unsigned lsb,
2277*f5c631daSSadaf Ebrahimi unsigned width) {
2278*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2279*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2280*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2281*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2282*f5c631daSSadaf Ebrahimi sbfiz(rd, rn, lsb, width);
2283*f5c631daSSadaf Ebrahimi }
Sbfm(const Register & rd,const Register & rn,unsigned immr,unsigned imms)2284*f5c631daSSadaf Ebrahimi void Sbfm(const Register& rd,
2285*f5c631daSSadaf Ebrahimi const Register& rn,
2286*f5c631daSSadaf Ebrahimi unsigned immr,
2287*f5c631daSSadaf Ebrahimi unsigned imms) {
2288*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2289*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2290*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2291*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2292*f5c631daSSadaf Ebrahimi sbfm(rd, rn, immr, imms);
2293*f5c631daSSadaf Ebrahimi }
Sbfx(const Register & rd,const Register & rn,unsigned lsb,unsigned width)2294*f5c631daSSadaf Ebrahimi void Sbfx(const Register& rd,
2295*f5c631daSSadaf Ebrahimi const Register& rn,
2296*f5c631daSSadaf Ebrahimi unsigned lsb,
2297*f5c631daSSadaf Ebrahimi unsigned width) {
2298*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2299*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2300*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2301*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2302*f5c631daSSadaf Ebrahimi sbfx(rd, rn, lsb, width);
2303*f5c631daSSadaf Ebrahimi }
2304*f5c631daSSadaf Ebrahimi void Scvtf(const VRegister& vd, const Register& rn, int fbits = 0) {
2305*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2306*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2307*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2308*f5c631daSSadaf Ebrahimi scvtf(vd, rn, fbits);
2309*f5c631daSSadaf Ebrahimi }
Sdiv(const Register & rd,const Register & rn,const Register & rm)2310*f5c631daSSadaf Ebrahimi void Sdiv(const Register& rd, const Register& rn, const Register& rm) {
2311*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2312*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2313*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2314*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rm.IsZero());
2315*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2316*f5c631daSSadaf Ebrahimi sdiv(rd, rn, rm);
2317*f5c631daSSadaf Ebrahimi }
Smaddl(const Register & rd,const Register & rn,const Register & rm,const Register & ra)2318*f5c631daSSadaf Ebrahimi void Smaddl(const Register& rd,
2319*f5c631daSSadaf Ebrahimi const Register& rn,
2320*f5c631daSSadaf Ebrahimi const Register& rm,
2321*f5c631daSSadaf Ebrahimi const Register& ra) {
2322*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2323*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2324*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2325*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rm.IsZero());
2326*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!ra.IsZero());
2327*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2328*f5c631daSSadaf Ebrahimi smaddl(rd, rn, rm, ra);
2329*f5c631daSSadaf Ebrahimi }
Smsubl(const Register & rd,const Register & rn,const Register & rm,const Register & ra)2330*f5c631daSSadaf Ebrahimi void Smsubl(const Register& rd,
2331*f5c631daSSadaf Ebrahimi const Register& rn,
2332*f5c631daSSadaf Ebrahimi const Register& rm,
2333*f5c631daSSadaf Ebrahimi const Register& ra) {
2334*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2335*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2336*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2337*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rm.IsZero());
2338*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!ra.IsZero());
2339*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2340*f5c631daSSadaf Ebrahimi smsubl(rd, rn, rm, ra);
2341*f5c631daSSadaf Ebrahimi }
Smull(const Register & rd,const Register & rn,const Register & rm)2342*f5c631daSSadaf Ebrahimi void Smull(const Register& rd, const Register& rn, const Register& rm) {
2343*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2344*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2345*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2346*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rm.IsZero());
2347*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2348*f5c631daSSadaf Ebrahimi smull(rd, rn, rm);
2349*f5c631daSSadaf Ebrahimi }
Smulh(const Register & xd,const Register & xn,const Register & xm)2350*f5c631daSSadaf Ebrahimi void Smulh(const Register& xd, const Register& xn, const Register& xm) {
2351*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2352*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!xd.IsZero());
2353*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!xn.IsZero());
2354*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!xm.IsZero());
2355*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2356*f5c631daSSadaf Ebrahimi smulh(xd, xn, xm);
2357*f5c631daSSadaf Ebrahimi }
Stlr(const Register & rt,const MemOperand & dst)2358*f5c631daSSadaf Ebrahimi void Stlr(const Register& rt, const MemOperand& dst) {
2359*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2360*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2361*f5c631daSSadaf Ebrahimi VIXL_ASSERT(dst.IsImmediateOffset());
2362*f5c631daSSadaf Ebrahimi if (dst.GetOffset() == 0) {
2363*f5c631daSSadaf Ebrahimi stlr(rt, dst);
2364*f5c631daSSadaf Ebrahimi } else {
2365*f5c631daSSadaf Ebrahimi stlur(rt, dst);
2366*f5c631daSSadaf Ebrahimi }
2367*f5c631daSSadaf Ebrahimi }
Stlrb(const Register & rt,const MemOperand & dst)2368*f5c631daSSadaf Ebrahimi void Stlrb(const Register& rt, const MemOperand& dst) {
2369*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2370*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2371*f5c631daSSadaf Ebrahimi VIXL_ASSERT(dst.IsImmediateOffset());
2372*f5c631daSSadaf Ebrahimi if (dst.GetOffset() == 0) {
2373*f5c631daSSadaf Ebrahimi stlrb(rt, dst);
2374*f5c631daSSadaf Ebrahimi } else {
2375*f5c631daSSadaf Ebrahimi stlurb(rt, dst);
2376*f5c631daSSadaf Ebrahimi }
2377*f5c631daSSadaf Ebrahimi }
Stlrh(const Register & rt,const MemOperand & dst)2378*f5c631daSSadaf Ebrahimi void Stlrh(const Register& rt, const MemOperand& dst) {
2379*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2380*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2381*f5c631daSSadaf Ebrahimi VIXL_ASSERT(dst.IsImmediateOffset());
2382*f5c631daSSadaf Ebrahimi if (dst.GetOffset() == 0) {
2383*f5c631daSSadaf Ebrahimi stlrh(rt, dst);
2384*f5c631daSSadaf Ebrahimi } else {
2385*f5c631daSSadaf Ebrahimi stlurh(rt, dst);
2386*f5c631daSSadaf Ebrahimi }
2387*f5c631daSSadaf Ebrahimi }
Stllr(const Register & rt,const MemOperand & dst)2388*f5c631daSSadaf Ebrahimi void Stllr(const Register& rt, const MemOperand& dst) {
2389*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2390*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2391*f5c631daSSadaf Ebrahimi stllr(rt, dst);
2392*f5c631daSSadaf Ebrahimi }
Stllrb(const Register & rt,const MemOperand & dst)2393*f5c631daSSadaf Ebrahimi void Stllrb(const Register& rt, const MemOperand& dst) {
2394*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2395*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2396*f5c631daSSadaf Ebrahimi stllrb(rt, dst);
2397*f5c631daSSadaf Ebrahimi }
Stllrh(const Register & rt,const MemOperand & dst)2398*f5c631daSSadaf Ebrahimi void Stllrh(const Register& rt, const MemOperand& dst) {
2399*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2400*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2401*f5c631daSSadaf Ebrahimi stllrh(rt, dst);
2402*f5c631daSSadaf Ebrahimi }
Stlxp(const Register & rs,const Register & rt,const Register & rt2,const MemOperand & dst)2403*f5c631daSSadaf Ebrahimi void Stlxp(const Register& rs,
2404*f5c631daSSadaf Ebrahimi const Register& rt,
2405*f5c631daSSadaf Ebrahimi const Register& rt2,
2406*f5c631daSSadaf Ebrahimi const MemOperand& dst) {
2407*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2408*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rs.Aliases(dst.GetBaseRegister()));
2409*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rs.Aliases(rt));
2410*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rs.Aliases(rt2));
2411*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2412*f5c631daSSadaf Ebrahimi stlxp(rs, rt, rt2, dst);
2413*f5c631daSSadaf Ebrahimi }
Stlxr(const Register & rs,const Register & rt,const MemOperand & dst)2414*f5c631daSSadaf Ebrahimi void Stlxr(const Register& rs, const Register& rt, const MemOperand& dst) {
2415*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2416*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rs.Aliases(dst.GetBaseRegister()));
2417*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rs.Aliases(rt));
2418*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2419*f5c631daSSadaf Ebrahimi stlxr(rs, rt, dst);
2420*f5c631daSSadaf Ebrahimi }
Stlxrb(const Register & rs,const Register & rt,const MemOperand & dst)2421*f5c631daSSadaf Ebrahimi void Stlxrb(const Register& rs, const Register& rt, const MemOperand& dst) {
2422*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2423*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rs.Aliases(dst.GetBaseRegister()));
2424*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rs.Aliases(rt));
2425*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2426*f5c631daSSadaf Ebrahimi stlxrb(rs, rt, dst);
2427*f5c631daSSadaf Ebrahimi }
Stlxrh(const Register & rs,const Register & rt,const MemOperand & dst)2428*f5c631daSSadaf Ebrahimi void Stlxrh(const Register& rs, const Register& rt, const MemOperand& dst) {
2429*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2430*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rs.Aliases(dst.GetBaseRegister()));
2431*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rs.Aliases(rt));
2432*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2433*f5c631daSSadaf Ebrahimi stlxrh(rs, rt, dst);
2434*f5c631daSSadaf Ebrahimi }
Stnp(const CPURegister & rt,const CPURegister & rt2,const MemOperand & dst)2435*f5c631daSSadaf Ebrahimi void Stnp(const CPURegister& rt,
2436*f5c631daSSadaf Ebrahimi const CPURegister& rt2,
2437*f5c631daSSadaf Ebrahimi const MemOperand& dst) {
2438*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2439*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2440*f5c631daSSadaf Ebrahimi stnp(rt, rt2, dst);
2441*f5c631daSSadaf Ebrahimi }
Stxp(const Register & rs,const Register & rt,const Register & rt2,const MemOperand & dst)2442*f5c631daSSadaf Ebrahimi void Stxp(const Register& rs,
2443*f5c631daSSadaf Ebrahimi const Register& rt,
2444*f5c631daSSadaf Ebrahimi const Register& rt2,
2445*f5c631daSSadaf Ebrahimi const MemOperand& dst) {
2446*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2447*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rs.Aliases(dst.GetBaseRegister()));
2448*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rs.Aliases(rt));
2449*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rs.Aliases(rt2));
2450*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2451*f5c631daSSadaf Ebrahimi stxp(rs, rt, rt2, dst);
2452*f5c631daSSadaf Ebrahimi }
Stxr(const Register & rs,const Register & rt,const MemOperand & dst)2453*f5c631daSSadaf Ebrahimi void Stxr(const Register& rs, const Register& rt, const MemOperand& dst) {
2454*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2455*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rs.Aliases(dst.GetBaseRegister()));
2456*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rs.Aliases(rt));
2457*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2458*f5c631daSSadaf Ebrahimi stxr(rs, rt, dst);
2459*f5c631daSSadaf Ebrahimi }
Stxrb(const Register & rs,const Register & rt,const MemOperand & dst)2460*f5c631daSSadaf Ebrahimi void Stxrb(const Register& rs, const Register& rt, const MemOperand& dst) {
2461*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2462*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rs.Aliases(dst.GetBaseRegister()));
2463*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rs.Aliases(rt));
2464*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2465*f5c631daSSadaf Ebrahimi stxrb(rs, rt, dst);
2466*f5c631daSSadaf Ebrahimi }
Stxrh(const Register & rs,const Register & rt,const MemOperand & dst)2467*f5c631daSSadaf Ebrahimi void Stxrh(const Register& rs, const Register& rt, const MemOperand& dst) {
2468*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2469*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rs.Aliases(dst.GetBaseRegister()));
2470*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rs.Aliases(rt));
2471*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2472*f5c631daSSadaf Ebrahimi stxrh(rs, rt, dst);
2473*f5c631daSSadaf Ebrahimi }
Svc(int code)2474*f5c631daSSadaf Ebrahimi void Svc(int code) {
2475*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2476*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2477*f5c631daSSadaf Ebrahimi svc(code);
2478*f5c631daSSadaf Ebrahimi }
Sxtb(const Register & rd,const Register & rn)2479*f5c631daSSadaf Ebrahimi void Sxtb(const Register& rd, const Register& rn) {
2480*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2481*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2482*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2483*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2484*f5c631daSSadaf Ebrahimi sxtb(rd, rn);
2485*f5c631daSSadaf Ebrahimi }
Sxth(const Register & rd,const Register & rn)2486*f5c631daSSadaf Ebrahimi void Sxth(const Register& rd, const Register& rn) {
2487*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2488*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2489*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2490*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2491*f5c631daSSadaf Ebrahimi sxth(rd, rn);
2492*f5c631daSSadaf Ebrahimi }
Sxtw(const Register & rd,const Register & rn)2493*f5c631daSSadaf Ebrahimi void Sxtw(const Register& rd, const Register& rn) {
2494*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2495*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2496*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2497*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2498*f5c631daSSadaf Ebrahimi sxtw(rd, rn);
2499*f5c631daSSadaf Ebrahimi }
Tbl(const VRegister & vd,const VRegister & vn,const VRegister & vm)2500*f5c631daSSadaf Ebrahimi void Tbl(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
2501*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2502*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2503*f5c631daSSadaf Ebrahimi tbl(vd, vn, vm);
2504*f5c631daSSadaf Ebrahimi }
Tbl(const VRegister & vd,const VRegister & vn,const VRegister & vn2,const VRegister & vm)2505*f5c631daSSadaf Ebrahimi void Tbl(const VRegister& vd,
2506*f5c631daSSadaf Ebrahimi const VRegister& vn,
2507*f5c631daSSadaf Ebrahimi const VRegister& vn2,
2508*f5c631daSSadaf Ebrahimi const VRegister& vm) {
2509*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2510*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2511*f5c631daSSadaf Ebrahimi tbl(vd, vn, vn2, vm);
2512*f5c631daSSadaf Ebrahimi }
Tbl(const VRegister & vd,const VRegister & vn,const VRegister & vn2,const VRegister & vn3,const VRegister & vm)2513*f5c631daSSadaf Ebrahimi void Tbl(const VRegister& vd,
2514*f5c631daSSadaf Ebrahimi const VRegister& vn,
2515*f5c631daSSadaf Ebrahimi const VRegister& vn2,
2516*f5c631daSSadaf Ebrahimi const VRegister& vn3,
2517*f5c631daSSadaf Ebrahimi const VRegister& vm) {
2518*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2519*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2520*f5c631daSSadaf Ebrahimi tbl(vd, vn, vn2, vn3, vm);
2521*f5c631daSSadaf Ebrahimi }
Tbl(const VRegister & vd,const VRegister & vn,const VRegister & vn2,const VRegister & vn3,const VRegister & vn4,const VRegister & vm)2522*f5c631daSSadaf Ebrahimi void Tbl(const VRegister& vd,
2523*f5c631daSSadaf Ebrahimi const VRegister& vn,
2524*f5c631daSSadaf Ebrahimi const VRegister& vn2,
2525*f5c631daSSadaf Ebrahimi const VRegister& vn3,
2526*f5c631daSSadaf Ebrahimi const VRegister& vn4,
2527*f5c631daSSadaf Ebrahimi const VRegister& vm) {
2528*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2529*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2530*f5c631daSSadaf Ebrahimi tbl(vd, vn, vn2, vn3, vn4, vm);
2531*f5c631daSSadaf Ebrahimi }
Tbx(const VRegister & vd,const VRegister & vn,const VRegister & vm)2532*f5c631daSSadaf Ebrahimi void Tbx(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
2533*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2534*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2535*f5c631daSSadaf Ebrahimi tbx(vd, vn, vm);
2536*f5c631daSSadaf Ebrahimi }
Tbx(const VRegister & vd,const VRegister & vn,const VRegister & vn2,const VRegister & vm)2537*f5c631daSSadaf Ebrahimi void Tbx(const VRegister& vd,
2538*f5c631daSSadaf Ebrahimi const VRegister& vn,
2539*f5c631daSSadaf Ebrahimi const VRegister& vn2,
2540*f5c631daSSadaf Ebrahimi const VRegister& vm) {
2541*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2542*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2543*f5c631daSSadaf Ebrahimi tbx(vd, vn, vn2, vm);
2544*f5c631daSSadaf Ebrahimi }
Tbx(const VRegister & vd,const VRegister & vn,const VRegister & vn2,const VRegister & vn3,const VRegister & vm)2545*f5c631daSSadaf Ebrahimi void Tbx(const VRegister& vd,
2546*f5c631daSSadaf Ebrahimi const VRegister& vn,
2547*f5c631daSSadaf Ebrahimi const VRegister& vn2,
2548*f5c631daSSadaf Ebrahimi const VRegister& vn3,
2549*f5c631daSSadaf Ebrahimi const VRegister& vm) {
2550*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2551*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2552*f5c631daSSadaf Ebrahimi tbx(vd, vn, vn2, vn3, vm);
2553*f5c631daSSadaf Ebrahimi }
Tbx(const VRegister & vd,const VRegister & vn,const VRegister & vn2,const VRegister & vn3,const VRegister & vn4,const VRegister & vm)2554*f5c631daSSadaf Ebrahimi void Tbx(const VRegister& vd,
2555*f5c631daSSadaf Ebrahimi const VRegister& vn,
2556*f5c631daSSadaf Ebrahimi const VRegister& vn2,
2557*f5c631daSSadaf Ebrahimi const VRegister& vn3,
2558*f5c631daSSadaf Ebrahimi const VRegister& vn4,
2559*f5c631daSSadaf Ebrahimi const VRegister& vm) {
2560*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2561*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2562*f5c631daSSadaf Ebrahimi tbx(vd, vn, vn2, vn3, vn4, vm);
2563*f5c631daSSadaf Ebrahimi }
2564*f5c631daSSadaf Ebrahimi void Tbnz(const Register& rt, unsigned bit_pos, Label* label);
2565*f5c631daSSadaf Ebrahimi void Tbz(const Register& rt, unsigned bit_pos, Label* label);
Ubfiz(const Register & rd,const Register & rn,unsigned lsb,unsigned width)2566*f5c631daSSadaf Ebrahimi void Ubfiz(const Register& rd,
2567*f5c631daSSadaf Ebrahimi const Register& rn,
2568*f5c631daSSadaf Ebrahimi unsigned lsb,
2569*f5c631daSSadaf Ebrahimi unsigned width) {
2570*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2571*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2572*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2573*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2574*f5c631daSSadaf Ebrahimi ubfiz(rd, rn, lsb, width);
2575*f5c631daSSadaf Ebrahimi }
Ubfm(const Register & rd,const Register & rn,unsigned immr,unsigned imms)2576*f5c631daSSadaf Ebrahimi void Ubfm(const Register& rd,
2577*f5c631daSSadaf Ebrahimi const Register& rn,
2578*f5c631daSSadaf Ebrahimi unsigned immr,
2579*f5c631daSSadaf Ebrahimi unsigned imms) {
2580*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2581*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2582*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2583*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2584*f5c631daSSadaf Ebrahimi ubfm(rd, rn, immr, imms);
2585*f5c631daSSadaf Ebrahimi }
Ubfx(const Register & rd,const Register & rn,unsigned lsb,unsigned width)2586*f5c631daSSadaf Ebrahimi void Ubfx(const Register& rd,
2587*f5c631daSSadaf Ebrahimi const Register& rn,
2588*f5c631daSSadaf Ebrahimi unsigned lsb,
2589*f5c631daSSadaf Ebrahimi unsigned width) {
2590*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2591*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2592*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2593*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2594*f5c631daSSadaf Ebrahimi ubfx(rd, rn, lsb, width);
2595*f5c631daSSadaf Ebrahimi }
2596*f5c631daSSadaf Ebrahimi void Ucvtf(const VRegister& vd, const Register& rn, int fbits = 0) {
2597*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2598*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2599*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2600*f5c631daSSadaf Ebrahimi ucvtf(vd, rn, fbits);
2601*f5c631daSSadaf Ebrahimi }
Udiv(const Register & rd,const Register & rn,const Register & rm)2602*f5c631daSSadaf Ebrahimi void Udiv(const Register& rd, const Register& rn, const Register& rm) {
2603*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2604*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2605*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2606*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rm.IsZero());
2607*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2608*f5c631daSSadaf Ebrahimi udiv(rd, rn, rm);
2609*f5c631daSSadaf Ebrahimi }
Umaddl(const Register & rd,const Register & rn,const Register & rm,const Register & ra)2610*f5c631daSSadaf Ebrahimi void Umaddl(const Register& rd,
2611*f5c631daSSadaf Ebrahimi const Register& rn,
2612*f5c631daSSadaf Ebrahimi const Register& rm,
2613*f5c631daSSadaf Ebrahimi const Register& ra) {
2614*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2615*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2616*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2617*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rm.IsZero());
2618*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!ra.IsZero());
2619*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2620*f5c631daSSadaf Ebrahimi umaddl(rd, rn, rm, ra);
2621*f5c631daSSadaf Ebrahimi }
Umull(const Register & rd,const Register & rn,const Register & rm)2622*f5c631daSSadaf Ebrahimi void Umull(const Register& rd, const Register& rn, const Register& rm) {
2623*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2624*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2625*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2626*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rm.IsZero());
2627*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2628*f5c631daSSadaf Ebrahimi umull(rd, rn, rm);
2629*f5c631daSSadaf Ebrahimi }
Umulh(const Register & xd,const Register & xn,const Register & xm)2630*f5c631daSSadaf Ebrahimi void Umulh(const Register& xd, const Register& xn, const Register& xm) {
2631*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2632*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!xd.IsZero());
2633*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!xn.IsZero());
2634*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!xm.IsZero());
2635*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2636*f5c631daSSadaf Ebrahimi umulh(xd, xn, xm);
2637*f5c631daSSadaf Ebrahimi }
Umsubl(const Register & rd,const Register & rn,const Register & rm,const Register & ra)2638*f5c631daSSadaf Ebrahimi void Umsubl(const Register& rd,
2639*f5c631daSSadaf Ebrahimi const Register& rn,
2640*f5c631daSSadaf Ebrahimi const Register& rm,
2641*f5c631daSSadaf Ebrahimi const Register& ra) {
2642*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2643*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2644*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2645*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rm.IsZero());
2646*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!ra.IsZero());
2647*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2648*f5c631daSSadaf Ebrahimi umsubl(rd, rn, rm, ra);
2649*f5c631daSSadaf Ebrahimi }
Unreachable()2650*f5c631daSSadaf Ebrahimi void Unreachable() {
2651*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2652*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2653*f5c631daSSadaf Ebrahimi if (generate_simulator_code_) {
2654*f5c631daSSadaf Ebrahimi hlt(kUnreachableOpcode);
2655*f5c631daSSadaf Ebrahimi } else {
2656*f5c631daSSadaf Ebrahimi // Use the architecturally-defined UDF instruction to abort on hardware,
2657*f5c631daSSadaf Ebrahimi // because using HLT and BRK tends to make the process difficult to debug.
2658*f5c631daSSadaf Ebrahimi udf(kUnreachableOpcode);
2659*f5c631daSSadaf Ebrahimi }
2660*f5c631daSSadaf Ebrahimi }
Uxtb(const Register & rd,const Register & rn)2661*f5c631daSSadaf Ebrahimi void Uxtb(const Register& rd, const Register& rn) {
2662*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2663*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2664*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2665*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2666*f5c631daSSadaf Ebrahimi uxtb(rd, rn);
2667*f5c631daSSadaf Ebrahimi }
Uxth(const Register & rd,const Register & rn)2668*f5c631daSSadaf Ebrahimi void Uxth(const Register& rd, const Register& rn) {
2669*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2670*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2671*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2672*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2673*f5c631daSSadaf Ebrahimi uxth(rd, rn);
2674*f5c631daSSadaf Ebrahimi }
Uxtw(const Register & rd,const Register & rn)2675*f5c631daSSadaf Ebrahimi void Uxtw(const Register& rd, const Register& rn) {
2676*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
2677*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rd.IsZero());
2678*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!rn.IsZero());
2679*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
2680*f5c631daSSadaf Ebrahimi uxtw(rd, rn);
2681*f5c631daSSadaf Ebrahimi }
2682*f5c631daSSadaf Ebrahimi
2683*f5c631daSSadaf Ebrahimi // NEON 3 vector register instructions.
2684*f5c631daSSadaf Ebrahimi #define NEON_3VREG_MACRO_LIST(V) \
2685*f5c631daSSadaf Ebrahimi V(add, Add) \
2686*f5c631daSSadaf Ebrahimi V(addhn, Addhn) \
2687*f5c631daSSadaf Ebrahimi V(addhn2, Addhn2) \
2688*f5c631daSSadaf Ebrahimi V(addp, Addp) \
2689*f5c631daSSadaf Ebrahimi V(and_, And) \
2690*f5c631daSSadaf Ebrahimi V(bic, Bic) \
2691*f5c631daSSadaf Ebrahimi V(bif, Bif) \
2692*f5c631daSSadaf Ebrahimi V(bit, Bit) \
2693*f5c631daSSadaf Ebrahimi V(bsl, Bsl) \
2694*f5c631daSSadaf Ebrahimi V(cmeq, Cmeq) \
2695*f5c631daSSadaf Ebrahimi V(cmge, Cmge) \
2696*f5c631daSSadaf Ebrahimi V(cmgt, Cmgt) \
2697*f5c631daSSadaf Ebrahimi V(cmhi, Cmhi) \
2698*f5c631daSSadaf Ebrahimi V(cmhs, Cmhs) \
2699*f5c631daSSadaf Ebrahimi V(cmtst, Cmtst) \
2700*f5c631daSSadaf Ebrahimi V(eor, Eor) \
2701*f5c631daSSadaf Ebrahimi V(fabd, Fabd) \
2702*f5c631daSSadaf Ebrahimi V(facge, Facge) \
2703*f5c631daSSadaf Ebrahimi V(facgt, Facgt) \
2704*f5c631daSSadaf Ebrahimi V(faddp, Faddp) \
2705*f5c631daSSadaf Ebrahimi V(fcmeq, Fcmeq) \
2706*f5c631daSSadaf Ebrahimi V(fcmge, Fcmge) \
2707*f5c631daSSadaf Ebrahimi V(fcmgt, Fcmgt) \
2708*f5c631daSSadaf Ebrahimi V(fmaxnmp, Fmaxnmp) \
2709*f5c631daSSadaf Ebrahimi V(fmaxp, Fmaxp) \
2710*f5c631daSSadaf Ebrahimi V(fminnmp, Fminnmp) \
2711*f5c631daSSadaf Ebrahimi V(fminp, Fminp) \
2712*f5c631daSSadaf Ebrahimi V(fmla, Fmla) \
2713*f5c631daSSadaf Ebrahimi V(fmlal, Fmlal) \
2714*f5c631daSSadaf Ebrahimi V(fmlal2, Fmlal2) \
2715*f5c631daSSadaf Ebrahimi V(fmls, Fmls) \
2716*f5c631daSSadaf Ebrahimi V(fmlsl, Fmlsl) \
2717*f5c631daSSadaf Ebrahimi V(fmlsl2, Fmlsl2) \
2718*f5c631daSSadaf Ebrahimi V(fmulx, Fmulx) \
2719*f5c631daSSadaf Ebrahimi V(frecps, Frecps) \
2720*f5c631daSSadaf Ebrahimi V(frsqrts, Frsqrts) \
2721*f5c631daSSadaf Ebrahimi V(mla, Mla) \
2722*f5c631daSSadaf Ebrahimi V(mls, Mls) \
2723*f5c631daSSadaf Ebrahimi V(mul, Mul) \
2724*f5c631daSSadaf Ebrahimi V(orn, Orn) \
2725*f5c631daSSadaf Ebrahimi V(orr, Orr) \
2726*f5c631daSSadaf Ebrahimi V(pmul, Pmul) \
2727*f5c631daSSadaf Ebrahimi V(pmull, Pmull) \
2728*f5c631daSSadaf Ebrahimi V(pmull2, Pmull2) \
2729*f5c631daSSadaf Ebrahimi V(raddhn, Raddhn) \
2730*f5c631daSSadaf Ebrahimi V(raddhn2, Raddhn2) \
2731*f5c631daSSadaf Ebrahimi V(rsubhn, Rsubhn) \
2732*f5c631daSSadaf Ebrahimi V(rsubhn2, Rsubhn2) \
2733*f5c631daSSadaf Ebrahimi V(saba, Saba) \
2734*f5c631daSSadaf Ebrahimi V(sabal, Sabal) \
2735*f5c631daSSadaf Ebrahimi V(sabal2, Sabal2) \
2736*f5c631daSSadaf Ebrahimi V(sabd, Sabd) \
2737*f5c631daSSadaf Ebrahimi V(sabdl, Sabdl) \
2738*f5c631daSSadaf Ebrahimi V(sabdl2, Sabdl2) \
2739*f5c631daSSadaf Ebrahimi V(saddl, Saddl) \
2740*f5c631daSSadaf Ebrahimi V(saddl2, Saddl2) \
2741*f5c631daSSadaf Ebrahimi V(saddw, Saddw) \
2742*f5c631daSSadaf Ebrahimi V(saddw2, Saddw2) \
2743*f5c631daSSadaf Ebrahimi V(shadd, Shadd) \
2744*f5c631daSSadaf Ebrahimi V(shsub, Shsub) \
2745*f5c631daSSadaf Ebrahimi V(smax, Smax) \
2746*f5c631daSSadaf Ebrahimi V(smaxp, Smaxp) \
2747*f5c631daSSadaf Ebrahimi V(smin, Smin) \
2748*f5c631daSSadaf Ebrahimi V(sminp, Sminp) \
2749*f5c631daSSadaf Ebrahimi V(smlal, Smlal) \
2750*f5c631daSSadaf Ebrahimi V(smlal2, Smlal2) \
2751*f5c631daSSadaf Ebrahimi V(smlsl, Smlsl) \
2752*f5c631daSSadaf Ebrahimi V(smlsl2, Smlsl2) \
2753*f5c631daSSadaf Ebrahimi V(smull, Smull) \
2754*f5c631daSSadaf Ebrahimi V(smull2, Smull2) \
2755*f5c631daSSadaf Ebrahimi V(sqadd, Sqadd) \
2756*f5c631daSSadaf Ebrahimi V(sqdmlal, Sqdmlal) \
2757*f5c631daSSadaf Ebrahimi V(sqdmlal2, Sqdmlal2) \
2758*f5c631daSSadaf Ebrahimi V(sqdmlsl, Sqdmlsl) \
2759*f5c631daSSadaf Ebrahimi V(sqdmlsl2, Sqdmlsl2) \
2760*f5c631daSSadaf Ebrahimi V(sqdmulh, Sqdmulh) \
2761*f5c631daSSadaf Ebrahimi V(sqdmull, Sqdmull) \
2762*f5c631daSSadaf Ebrahimi V(sqdmull2, Sqdmull2) \
2763*f5c631daSSadaf Ebrahimi V(sqrdmulh, Sqrdmulh) \
2764*f5c631daSSadaf Ebrahimi V(sdot, Sdot) \
2765*f5c631daSSadaf Ebrahimi V(sqrdmlah, Sqrdmlah) \
2766*f5c631daSSadaf Ebrahimi V(udot, Udot) \
2767*f5c631daSSadaf Ebrahimi V(sqrdmlsh, Sqrdmlsh) \
2768*f5c631daSSadaf Ebrahimi V(sqrshl, Sqrshl) \
2769*f5c631daSSadaf Ebrahimi V(sqshl, Sqshl) \
2770*f5c631daSSadaf Ebrahimi V(sqsub, Sqsub) \
2771*f5c631daSSadaf Ebrahimi V(srhadd, Srhadd) \
2772*f5c631daSSadaf Ebrahimi V(srshl, Srshl) \
2773*f5c631daSSadaf Ebrahimi V(sshl, Sshl) \
2774*f5c631daSSadaf Ebrahimi V(ssubl, Ssubl) \
2775*f5c631daSSadaf Ebrahimi V(ssubl2, Ssubl2) \
2776*f5c631daSSadaf Ebrahimi V(ssubw, Ssubw) \
2777*f5c631daSSadaf Ebrahimi V(ssubw2, Ssubw2) \
2778*f5c631daSSadaf Ebrahimi V(sub, Sub) \
2779*f5c631daSSadaf Ebrahimi V(subhn, Subhn) \
2780*f5c631daSSadaf Ebrahimi V(subhn2, Subhn2) \
2781*f5c631daSSadaf Ebrahimi V(trn1, Trn1) \
2782*f5c631daSSadaf Ebrahimi V(trn2, Trn2) \
2783*f5c631daSSadaf Ebrahimi V(uaba, Uaba) \
2784*f5c631daSSadaf Ebrahimi V(uabal, Uabal) \
2785*f5c631daSSadaf Ebrahimi V(uabal2, Uabal2) \
2786*f5c631daSSadaf Ebrahimi V(uabd, Uabd) \
2787*f5c631daSSadaf Ebrahimi V(uabdl, Uabdl) \
2788*f5c631daSSadaf Ebrahimi V(uabdl2, Uabdl2) \
2789*f5c631daSSadaf Ebrahimi V(uaddl, Uaddl) \
2790*f5c631daSSadaf Ebrahimi V(uaddl2, Uaddl2) \
2791*f5c631daSSadaf Ebrahimi V(uaddw, Uaddw) \
2792*f5c631daSSadaf Ebrahimi V(uaddw2, Uaddw2) \
2793*f5c631daSSadaf Ebrahimi V(uhadd, Uhadd) \
2794*f5c631daSSadaf Ebrahimi V(uhsub, Uhsub) \
2795*f5c631daSSadaf Ebrahimi V(umax, Umax) \
2796*f5c631daSSadaf Ebrahimi V(umaxp, Umaxp) \
2797*f5c631daSSadaf Ebrahimi V(umin, Umin) \
2798*f5c631daSSadaf Ebrahimi V(uminp, Uminp) \
2799*f5c631daSSadaf Ebrahimi V(umlal, Umlal) \
2800*f5c631daSSadaf Ebrahimi V(umlal2, Umlal2) \
2801*f5c631daSSadaf Ebrahimi V(umlsl, Umlsl) \
2802*f5c631daSSadaf Ebrahimi V(umlsl2, Umlsl2) \
2803*f5c631daSSadaf Ebrahimi V(umull, Umull) \
2804*f5c631daSSadaf Ebrahimi V(umull2, Umull2) \
2805*f5c631daSSadaf Ebrahimi V(uqadd, Uqadd) \
2806*f5c631daSSadaf Ebrahimi V(uqrshl, Uqrshl) \
2807*f5c631daSSadaf Ebrahimi V(uqshl, Uqshl) \
2808*f5c631daSSadaf Ebrahimi V(uqsub, Uqsub) \
2809*f5c631daSSadaf Ebrahimi V(urhadd, Urhadd) \
2810*f5c631daSSadaf Ebrahimi V(urshl, Urshl) \
2811*f5c631daSSadaf Ebrahimi V(ushl, Ushl) \
2812*f5c631daSSadaf Ebrahimi V(usubl, Usubl) \
2813*f5c631daSSadaf Ebrahimi V(usubl2, Usubl2) \
2814*f5c631daSSadaf Ebrahimi V(usubw, Usubw) \
2815*f5c631daSSadaf Ebrahimi V(usubw2, Usubw2) \
2816*f5c631daSSadaf Ebrahimi V(uzp1, Uzp1) \
2817*f5c631daSSadaf Ebrahimi V(uzp2, Uzp2) \
2818*f5c631daSSadaf Ebrahimi V(zip1, Zip1) \
2819*f5c631daSSadaf Ebrahimi V(zip2, Zip2) \
2820*f5c631daSSadaf Ebrahimi V(smmla, Smmla) \
2821*f5c631daSSadaf Ebrahimi V(ummla, Ummla) \
2822*f5c631daSSadaf Ebrahimi V(usmmla, Usmmla) \
2823*f5c631daSSadaf Ebrahimi V(usdot, Usdot)
2824*f5c631daSSadaf Ebrahimi
2825*f5c631daSSadaf Ebrahimi #define DEFINE_MACRO_ASM_FUNC(ASM, MASM) \
2826*f5c631daSSadaf Ebrahimi void MASM(const VRegister& vd, const VRegister& vn, const VRegister& vm) { \
2827*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_); \
2828*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this); \
2829*f5c631daSSadaf Ebrahimi ASM(vd, vn, vm); \
2830*f5c631daSSadaf Ebrahimi }
2831*f5c631daSSadaf Ebrahimi NEON_3VREG_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
2832*f5c631daSSadaf Ebrahimi #undef DEFINE_MACRO_ASM_FUNC
2833*f5c631daSSadaf Ebrahimi
2834*f5c631daSSadaf Ebrahimi // NEON 2 vector register instructions.
2835*f5c631daSSadaf Ebrahimi #define NEON_2VREG_MACRO_LIST(V) \
2836*f5c631daSSadaf Ebrahimi V(abs, Abs) \
2837*f5c631daSSadaf Ebrahimi V(addp, Addp) \
2838*f5c631daSSadaf Ebrahimi V(addv, Addv) \
2839*f5c631daSSadaf Ebrahimi V(cls, Cls) \
2840*f5c631daSSadaf Ebrahimi V(clz, Clz) \
2841*f5c631daSSadaf Ebrahimi V(cnt, Cnt) \
2842*f5c631daSSadaf Ebrahimi V(fabs, Fabs) \
2843*f5c631daSSadaf Ebrahimi V(faddp, Faddp) \
2844*f5c631daSSadaf Ebrahimi V(fcvtas, Fcvtas) \
2845*f5c631daSSadaf Ebrahimi V(fcvtau, Fcvtau) \
2846*f5c631daSSadaf Ebrahimi V(fcvtms, Fcvtms) \
2847*f5c631daSSadaf Ebrahimi V(fcvtmu, Fcvtmu) \
2848*f5c631daSSadaf Ebrahimi V(fcvtns, Fcvtns) \
2849*f5c631daSSadaf Ebrahimi V(fcvtnu, Fcvtnu) \
2850*f5c631daSSadaf Ebrahimi V(fcvtps, Fcvtps) \
2851*f5c631daSSadaf Ebrahimi V(fcvtpu, Fcvtpu) \
2852*f5c631daSSadaf Ebrahimi V(fmaxnmp, Fmaxnmp) \
2853*f5c631daSSadaf Ebrahimi V(fmaxnmv, Fmaxnmv) \
2854*f5c631daSSadaf Ebrahimi V(fmaxp, Fmaxp) \
2855*f5c631daSSadaf Ebrahimi V(fmaxv, Fmaxv) \
2856*f5c631daSSadaf Ebrahimi V(fminnmp, Fminnmp) \
2857*f5c631daSSadaf Ebrahimi V(fminnmv, Fminnmv) \
2858*f5c631daSSadaf Ebrahimi V(fminp, Fminp) \
2859*f5c631daSSadaf Ebrahimi V(fminv, Fminv) \
2860*f5c631daSSadaf Ebrahimi V(fneg, Fneg) \
2861*f5c631daSSadaf Ebrahimi V(frecpe, Frecpe) \
2862*f5c631daSSadaf Ebrahimi V(frecpx, Frecpx) \
2863*f5c631daSSadaf Ebrahimi V(frint32x, Frint32x) \
2864*f5c631daSSadaf Ebrahimi V(frint32z, Frint32z) \
2865*f5c631daSSadaf Ebrahimi V(frint64x, Frint64x) \
2866*f5c631daSSadaf Ebrahimi V(frint64z, Frint64z) \
2867*f5c631daSSadaf Ebrahimi V(frinta, Frinta) \
2868*f5c631daSSadaf Ebrahimi V(frinti, Frinti) \
2869*f5c631daSSadaf Ebrahimi V(frintm, Frintm) \
2870*f5c631daSSadaf Ebrahimi V(frintn, Frintn) \
2871*f5c631daSSadaf Ebrahimi V(frintp, Frintp) \
2872*f5c631daSSadaf Ebrahimi V(frintx, Frintx) \
2873*f5c631daSSadaf Ebrahimi V(frintz, Frintz) \
2874*f5c631daSSadaf Ebrahimi V(frsqrte, Frsqrte) \
2875*f5c631daSSadaf Ebrahimi V(fsqrt, Fsqrt) \
2876*f5c631daSSadaf Ebrahimi V(mov, Mov) \
2877*f5c631daSSadaf Ebrahimi V(mvn, Mvn) \
2878*f5c631daSSadaf Ebrahimi V(neg, Neg) \
2879*f5c631daSSadaf Ebrahimi V(not_, Not) \
2880*f5c631daSSadaf Ebrahimi V(rbit, Rbit) \
2881*f5c631daSSadaf Ebrahimi V(rev16, Rev16) \
2882*f5c631daSSadaf Ebrahimi V(rev32, Rev32) \
2883*f5c631daSSadaf Ebrahimi V(rev64, Rev64) \
2884*f5c631daSSadaf Ebrahimi V(sadalp, Sadalp) \
2885*f5c631daSSadaf Ebrahimi V(saddlp, Saddlp) \
2886*f5c631daSSadaf Ebrahimi V(saddlv, Saddlv) \
2887*f5c631daSSadaf Ebrahimi V(smaxv, Smaxv) \
2888*f5c631daSSadaf Ebrahimi V(sminv, Sminv) \
2889*f5c631daSSadaf Ebrahimi V(sqabs, Sqabs) \
2890*f5c631daSSadaf Ebrahimi V(sqneg, Sqneg) \
2891*f5c631daSSadaf Ebrahimi V(sqxtn, Sqxtn) \
2892*f5c631daSSadaf Ebrahimi V(sqxtn2, Sqxtn2) \
2893*f5c631daSSadaf Ebrahimi V(sqxtun, Sqxtun) \
2894*f5c631daSSadaf Ebrahimi V(sqxtun2, Sqxtun2) \
2895*f5c631daSSadaf Ebrahimi V(suqadd, Suqadd) \
2896*f5c631daSSadaf Ebrahimi V(sxtl, Sxtl) \
2897*f5c631daSSadaf Ebrahimi V(sxtl2, Sxtl2) \
2898*f5c631daSSadaf Ebrahimi V(uadalp, Uadalp) \
2899*f5c631daSSadaf Ebrahimi V(uaddlp, Uaddlp) \
2900*f5c631daSSadaf Ebrahimi V(uaddlv, Uaddlv) \
2901*f5c631daSSadaf Ebrahimi V(umaxv, Umaxv) \
2902*f5c631daSSadaf Ebrahimi V(uminv, Uminv) \
2903*f5c631daSSadaf Ebrahimi V(uqxtn, Uqxtn) \
2904*f5c631daSSadaf Ebrahimi V(uqxtn2, Uqxtn2) \
2905*f5c631daSSadaf Ebrahimi V(urecpe, Urecpe) \
2906*f5c631daSSadaf Ebrahimi V(ursqrte, Ursqrte) \
2907*f5c631daSSadaf Ebrahimi V(usqadd, Usqadd) \
2908*f5c631daSSadaf Ebrahimi V(uxtl, Uxtl) \
2909*f5c631daSSadaf Ebrahimi V(uxtl2, Uxtl2) \
2910*f5c631daSSadaf Ebrahimi V(xtn, Xtn) \
2911*f5c631daSSadaf Ebrahimi V(xtn2, Xtn2)
2912*f5c631daSSadaf Ebrahimi
2913*f5c631daSSadaf Ebrahimi #define DEFINE_MACRO_ASM_FUNC(ASM, MASM) \
2914*f5c631daSSadaf Ebrahimi void MASM(const VRegister& vd, const VRegister& vn) { \
2915*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_); \
2916*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this); \
2917*f5c631daSSadaf Ebrahimi ASM(vd, vn); \
2918*f5c631daSSadaf Ebrahimi }
NEON_2VREG_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)2919*f5c631daSSadaf Ebrahimi NEON_2VREG_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
2920*f5c631daSSadaf Ebrahimi #undef DEFINE_MACRO_ASM_FUNC
2921*f5c631daSSadaf Ebrahimi
2922*f5c631daSSadaf Ebrahimi // NEON 2 vector register with immediate instructions.
2923*f5c631daSSadaf Ebrahimi #define NEON_2VREG_FPIMM_MACRO_LIST(V) \
2924*f5c631daSSadaf Ebrahimi V(fcmeq, Fcmeq) \
2925*f5c631daSSadaf Ebrahimi V(fcmge, Fcmge) \
2926*f5c631daSSadaf Ebrahimi V(fcmgt, Fcmgt) \
2927*f5c631daSSadaf Ebrahimi V(fcmle, Fcmle) \
2928*f5c631daSSadaf Ebrahimi V(fcmlt, Fcmlt)
2929*f5c631daSSadaf Ebrahimi
2930*f5c631daSSadaf Ebrahimi #define DEFINE_MACRO_ASM_FUNC(ASM, MASM) \
2931*f5c631daSSadaf Ebrahimi void MASM(const VRegister& vd, const VRegister& vn, double imm) { \
2932*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_); \
2933*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this); \
2934*f5c631daSSadaf Ebrahimi ASM(vd, vn, imm); \
2935*f5c631daSSadaf Ebrahimi }
2936*f5c631daSSadaf Ebrahimi NEON_2VREG_FPIMM_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
2937*f5c631daSSadaf Ebrahimi #undef DEFINE_MACRO_ASM_FUNC
2938*f5c631daSSadaf Ebrahimi
2939*f5c631daSSadaf Ebrahimi // NEON by element instructions.
2940*f5c631daSSadaf Ebrahimi #define NEON_BYELEMENT_MACRO_LIST(V) \
2941*f5c631daSSadaf Ebrahimi V(fmul, Fmul) \
2942*f5c631daSSadaf Ebrahimi V(fmla, Fmla) \
2943*f5c631daSSadaf Ebrahimi V(fmlal, Fmlal) \
2944*f5c631daSSadaf Ebrahimi V(fmlal2, Fmlal2) \
2945*f5c631daSSadaf Ebrahimi V(fmls, Fmls) \
2946*f5c631daSSadaf Ebrahimi V(fmlsl, Fmlsl) \
2947*f5c631daSSadaf Ebrahimi V(fmlsl2, Fmlsl2) \
2948*f5c631daSSadaf Ebrahimi V(fmulx, Fmulx) \
2949*f5c631daSSadaf Ebrahimi V(mul, Mul) \
2950*f5c631daSSadaf Ebrahimi V(mla, Mla) \
2951*f5c631daSSadaf Ebrahimi V(mls, Mls) \
2952*f5c631daSSadaf Ebrahimi V(sqdmulh, Sqdmulh) \
2953*f5c631daSSadaf Ebrahimi V(sqrdmulh, Sqrdmulh) \
2954*f5c631daSSadaf Ebrahimi V(sdot, Sdot) \
2955*f5c631daSSadaf Ebrahimi V(sqrdmlah, Sqrdmlah) \
2956*f5c631daSSadaf Ebrahimi V(udot, Udot) \
2957*f5c631daSSadaf Ebrahimi V(sqrdmlsh, Sqrdmlsh) \
2958*f5c631daSSadaf Ebrahimi V(sqdmull, Sqdmull) \
2959*f5c631daSSadaf Ebrahimi V(sqdmull2, Sqdmull2) \
2960*f5c631daSSadaf Ebrahimi V(sqdmlal, Sqdmlal) \
2961*f5c631daSSadaf Ebrahimi V(sqdmlal2, Sqdmlal2) \
2962*f5c631daSSadaf Ebrahimi V(sqdmlsl, Sqdmlsl) \
2963*f5c631daSSadaf Ebrahimi V(sqdmlsl2, Sqdmlsl2) \
2964*f5c631daSSadaf Ebrahimi V(smull, Smull) \
2965*f5c631daSSadaf Ebrahimi V(smull2, Smull2) \
2966*f5c631daSSadaf Ebrahimi V(smlal, Smlal) \
2967*f5c631daSSadaf Ebrahimi V(smlal2, Smlal2) \
2968*f5c631daSSadaf Ebrahimi V(smlsl, Smlsl) \
2969*f5c631daSSadaf Ebrahimi V(smlsl2, Smlsl2) \
2970*f5c631daSSadaf Ebrahimi V(umull, Umull) \
2971*f5c631daSSadaf Ebrahimi V(umull2, Umull2) \
2972*f5c631daSSadaf Ebrahimi V(umlal, Umlal) \
2973*f5c631daSSadaf Ebrahimi V(umlal2, Umlal2) \
2974*f5c631daSSadaf Ebrahimi V(umlsl, Umlsl) \
2975*f5c631daSSadaf Ebrahimi V(umlsl2, Umlsl2) \
2976*f5c631daSSadaf Ebrahimi V(sudot, Sudot) \
2977*f5c631daSSadaf Ebrahimi V(usdot, Usdot)
2978*f5c631daSSadaf Ebrahimi
2979*f5c631daSSadaf Ebrahimi
2980*f5c631daSSadaf Ebrahimi #define DEFINE_MACRO_ASM_FUNC(ASM, MASM) \
2981*f5c631daSSadaf Ebrahimi void MASM(const VRegister& vd, \
2982*f5c631daSSadaf Ebrahimi const VRegister& vn, \
2983*f5c631daSSadaf Ebrahimi const VRegister& vm, \
2984*f5c631daSSadaf Ebrahimi int vm_index) { \
2985*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_); \
2986*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this); \
2987*f5c631daSSadaf Ebrahimi ASM(vd, vn, vm, vm_index); \
2988*f5c631daSSadaf Ebrahimi }
2989*f5c631daSSadaf Ebrahimi NEON_BYELEMENT_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
2990*f5c631daSSadaf Ebrahimi #undef DEFINE_MACRO_ASM_FUNC
2991*f5c631daSSadaf Ebrahimi
2992*f5c631daSSadaf Ebrahimi #define NEON_2VREG_SHIFT_MACRO_LIST(V) \
2993*f5c631daSSadaf Ebrahimi V(rshrn, Rshrn) \
2994*f5c631daSSadaf Ebrahimi V(rshrn2, Rshrn2) \
2995*f5c631daSSadaf Ebrahimi V(shl, Shl) \
2996*f5c631daSSadaf Ebrahimi V(shll, Shll) \
2997*f5c631daSSadaf Ebrahimi V(shll2, Shll2) \
2998*f5c631daSSadaf Ebrahimi V(shrn, Shrn) \
2999*f5c631daSSadaf Ebrahimi V(shrn2, Shrn2) \
3000*f5c631daSSadaf Ebrahimi V(sli, Sli) \
3001*f5c631daSSadaf Ebrahimi V(sqrshrn, Sqrshrn) \
3002*f5c631daSSadaf Ebrahimi V(sqrshrn2, Sqrshrn2) \
3003*f5c631daSSadaf Ebrahimi V(sqrshrun, Sqrshrun) \
3004*f5c631daSSadaf Ebrahimi V(sqrshrun2, Sqrshrun2) \
3005*f5c631daSSadaf Ebrahimi V(sqshl, Sqshl) \
3006*f5c631daSSadaf Ebrahimi V(sqshlu, Sqshlu) \
3007*f5c631daSSadaf Ebrahimi V(sqshrn, Sqshrn) \
3008*f5c631daSSadaf Ebrahimi V(sqshrn2, Sqshrn2) \
3009*f5c631daSSadaf Ebrahimi V(sqshrun, Sqshrun) \
3010*f5c631daSSadaf Ebrahimi V(sqshrun2, Sqshrun2) \
3011*f5c631daSSadaf Ebrahimi V(sri, Sri) \
3012*f5c631daSSadaf Ebrahimi V(srshr, Srshr) \
3013*f5c631daSSadaf Ebrahimi V(srsra, Srsra) \
3014*f5c631daSSadaf Ebrahimi V(sshr, Sshr) \
3015*f5c631daSSadaf Ebrahimi V(ssra, Ssra) \
3016*f5c631daSSadaf Ebrahimi V(uqrshrn, Uqrshrn) \
3017*f5c631daSSadaf Ebrahimi V(uqrshrn2, Uqrshrn2) \
3018*f5c631daSSadaf Ebrahimi V(uqshl, Uqshl) \
3019*f5c631daSSadaf Ebrahimi V(uqshrn, Uqshrn) \
3020*f5c631daSSadaf Ebrahimi V(uqshrn2, Uqshrn2) \
3021*f5c631daSSadaf Ebrahimi V(urshr, Urshr) \
3022*f5c631daSSadaf Ebrahimi V(ursra, Ursra) \
3023*f5c631daSSadaf Ebrahimi V(ushr, Ushr) \
3024*f5c631daSSadaf Ebrahimi V(usra, Usra)
3025*f5c631daSSadaf Ebrahimi
3026*f5c631daSSadaf Ebrahimi #define DEFINE_MACRO_ASM_FUNC(ASM, MASM) \
3027*f5c631daSSadaf Ebrahimi void MASM(const VRegister& vd, const VRegister& vn, int shift) { \
3028*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_); \
3029*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this); \
3030*f5c631daSSadaf Ebrahimi ASM(vd, vn, shift); \
3031*f5c631daSSadaf Ebrahimi }
3032*f5c631daSSadaf Ebrahimi NEON_2VREG_SHIFT_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
3033*f5c631daSSadaf Ebrahimi #undef DEFINE_MACRO_ASM_FUNC
3034*f5c631daSSadaf Ebrahimi
3035*f5c631daSSadaf Ebrahimi #define NEON_2VREG_SHIFT_LONG_MACRO_LIST(V) \
3036*f5c631daSSadaf Ebrahimi V(shll, sshll, Sshll) \
3037*f5c631daSSadaf Ebrahimi V(shll, ushll, Ushll) \
3038*f5c631daSSadaf Ebrahimi V(shll2, sshll2, Sshll2) \
3039*f5c631daSSadaf Ebrahimi V(shll2, ushll2, Ushll2)
3040*f5c631daSSadaf Ebrahimi
3041*f5c631daSSadaf Ebrahimi #define DEFINE_MACRO_ASM_FUNC(ASM1, ASM2, MASM) \
3042*f5c631daSSadaf Ebrahimi void MASM(const VRegister& vd, const VRegister& vn, int shift) { \
3043*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_); \
3044*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this); \
3045*f5c631daSSadaf Ebrahimi if (vn.GetLaneSizeInBits() == static_cast<unsigned>(shift)) { \
3046*f5c631daSSadaf Ebrahimi ASM1(vd, vn, shift); \
3047*f5c631daSSadaf Ebrahimi } else { \
3048*f5c631daSSadaf Ebrahimi ASM2(vd, vn, shift); \
3049*f5c631daSSadaf Ebrahimi } \
3050*f5c631daSSadaf Ebrahimi }
3051*f5c631daSSadaf Ebrahimi NEON_2VREG_SHIFT_LONG_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
3052*f5c631daSSadaf Ebrahimi #undef DEFINE_MACRO_ASM_FUNC
3053*f5c631daSSadaf Ebrahimi
3054*f5c631daSSadaf Ebrahimi // SVE 3 vector register instructions.
3055*f5c631daSSadaf Ebrahimi #define SVE_3VREG_COMMUTATIVE_MACRO_LIST(V) \
3056*f5c631daSSadaf Ebrahimi V(add, Add) \
3057*f5c631daSSadaf Ebrahimi V(and_, And) \
3058*f5c631daSSadaf Ebrahimi V(bic, Bic) \
3059*f5c631daSSadaf Ebrahimi V(eor, Eor) \
3060*f5c631daSSadaf Ebrahimi V(mul, Mul) \
3061*f5c631daSSadaf Ebrahimi V(orr, Orr) \
3062*f5c631daSSadaf Ebrahimi V(sabd, Sabd) \
3063*f5c631daSSadaf Ebrahimi V(shadd, Shadd) \
3064*f5c631daSSadaf Ebrahimi V(smax, Smax) \
3065*f5c631daSSadaf Ebrahimi V(smin, Smin) \
3066*f5c631daSSadaf Ebrahimi V(smulh, Smulh) \
3067*f5c631daSSadaf Ebrahimi V(sqadd, Sqadd) \
3068*f5c631daSSadaf Ebrahimi V(srhadd, Srhadd) \
3069*f5c631daSSadaf Ebrahimi V(uabd, Uabd) \
3070*f5c631daSSadaf Ebrahimi V(uhadd, Uhadd) \
3071*f5c631daSSadaf Ebrahimi V(umax, Umax) \
3072*f5c631daSSadaf Ebrahimi V(umin, Umin) \
3073*f5c631daSSadaf Ebrahimi V(umulh, Umulh) \
3074*f5c631daSSadaf Ebrahimi V(uqadd, Uqadd) \
3075*f5c631daSSadaf Ebrahimi V(urhadd, Urhadd)
3076*f5c631daSSadaf Ebrahimi
3077*f5c631daSSadaf Ebrahimi #define DEFINE_MACRO_ASM_FUNC(ASM, MASM) \
3078*f5c631daSSadaf Ebrahimi void MASM(const ZRegister& zd, \
3079*f5c631daSSadaf Ebrahimi const PRegisterM& pg, \
3080*f5c631daSSadaf Ebrahimi const ZRegister& zn, \
3081*f5c631daSSadaf Ebrahimi const ZRegister& zm) { \
3082*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_); \
3083*f5c631daSSadaf Ebrahimi if (zd.Aliases(zn)) { \
3084*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this); \
3085*f5c631daSSadaf Ebrahimi ASM(zd, pg, zd, zm); \
3086*f5c631daSSadaf Ebrahimi } else if (zd.Aliases(zm)) { \
3087*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this); \
3088*f5c631daSSadaf Ebrahimi ASM(zd, pg, zd, zn); \
3089*f5c631daSSadaf Ebrahimi } else { \
3090*f5c631daSSadaf Ebrahimi MovprfxHelperScope guard(this, zd, pg, zn); \
3091*f5c631daSSadaf Ebrahimi ASM(zd, pg, zd, zm); \
3092*f5c631daSSadaf Ebrahimi } \
3093*f5c631daSSadaf Ebrahimi }
3094*f5c631daSSadaf Ebrahimi SVE_3VREG_COMMUTATIVE_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
3095*f5c631daSSadaf Ebrahimi #undef DEFINE_MACRO_ASM_FUNC
3096*f5c631daSSadaf Ebrahimi
3097*f5c631daSSadaf Ebrahimi void Bic(const VRegister& vd, const int imm8, const int left_shift = 0) {
3098*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3099*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3100*f5c631daSSadaf Ebrahimi bic(vd, imm8, left_shift);
3101*f5c631daSSadaf Ebrahimi }
Cmeq(const VRegister & vd,const VRegister & vn,int imm)3102*f5c631daSSadaf Ebrahimi void Cmeq(const VRegister& vd, const VRegister& vn, int imm) {
3103*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3104*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3105*f5c631daSSadaf Ebrahimi cmeq(vd, vn, imm);
3106*f5c631daSSadaf Ebrahimi }
Cmge(const VRegister & vd,const VRegister & vn,int imm)3107*f5c631daSSadaf Ebrahimi void Cmge(const VRegister& vd, const VRegister& vn, int imm) {
3108*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3109*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3110*f5c631daSSadaf Ebrahimi cmge(vd, vn, imm);
3111*f5c631daSSadaf Ebrahimi }
Cmgt(const VRegister & vd,const VRegister & vn,int imm)3112*f5c631daSSadaf Ebrahimi void Cmgt(const VRegister& vd, const VRegister& vn, int imm) {
3113*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3114*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3115*f5c631daSSadaf Ebrahimi cmgt(vd, vn, imm);
3116*f5c631daSSadaf Ebrahimi }
Cmle(const VRegister & vd,const VRegister & vn,int imm)3117*f5c631daSSadaf Ebrahimi void Cmle(const VRegister& vd, const VRegister& vn, int imm) {
3118*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3119*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3120*f5c631daSSadaf Ebrahimi cmle(vd, vn, imm);
3121*f5c631daSSadaf Ebrahimi }
Cmlt(const VRegister & vd,const VRegister & vn,int imm)3122*f5c631daSSadaf Ebrahimi void Cmlt(const VRegister& vd, const VRegister& vn, int imm) {
3123*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3124*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3125*f5c631daSSadaf Ebrahimi cmlt(vd, vn, imm);
3126*f5c631daSSadaf Ebrahimi }
Dup(const VRegister & vd,const VRegister & vn,int index)3127*f5c631daSSadaf Ebrahimi void Dup(const VRegister& vd, const VRegister& vn, int index) {
3128*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3129*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3130*f5c631daSSadaf Ebrahimi dup(vd, vn, index);
3131*f5c631daSSadaf Ebrahimi }
Dup(const VRegister & vd,const Register & rn)3132*f5c631daSSadaf Ebrahimi void Dup(const VRegister& vd, const Register& rn) {
3133*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3134*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3135*f5c631daSSadaf Ebrahimi dup(vd, rn);
3136*f5c631daSSadaf Ebrahimi }
Ext(const VRegister & vd,const VRegister & vn,const VRegister & vm,int index)3137*f5c631daSSadaf Ebrahimi void Ext(const VRegister& vd,
3138*f5c631daSSadaf Ebrahimi const VRegister& vn,
3139*f5c631daSSadaf Ebrahimi const VRegister& vm,
3140*f5c631daSSadaf Ebrahimi int index) {
3141*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3142*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3143*f5c631daSSadaf Ebrahimi ext(vd, vn, vm, index);
3144*f5c631daSSadaf Ebrahimi }
Fcadd(const VRegister & vd,const VRegister & vn,const VRegister & vm,int rot)3145*f5c631daSSadaf Ebrahimi void Fcadd(const VRegister& vd,
3146*f5c631daSSadaf Ebrahimi const VRegister& vn,
3147*f5c631daSSadaf Ebrahimi const VRegister& vm,
3148*f5c631daSSadaf Ebrahimi int rot) {
3149*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3150*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3151*f5c631daSSadaf Ebrahimi fcadd(vd, vn, vm, rot);
3152*f5c631daSSadaf Ebrahimi }
Fcmla(const VRegister & vd,const VRegister & vn,const VRegister & vm,int vm_index,int rot)3153*f5c631daSSadaf Ebrahimi void Fcmla(const VRegister& vd,
3154*f5c631daSSadaf Ebrahimi const VRegister& vn,
3155*f5c631daSSadaf Ebrahimi const VRegister& vm,
3156*f5c631daSSadaf Ebrahimi int vm_index,
3157*f5c631daSSadaf Ebrahimi int rot) {
3158*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3159*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3160*f5c631daSSadaf Ebrahimi fcmla(vd, vn, vm, vm_index, rot);
3161*f5c631daSSadaf Ebrahimi }
Fcmla(const VRegister & vd,const VRegister & vn,const VRegister & vm,int rot)3162*f5c631daSSadaf Ebrahimi void Fcmla(const VRegister& vd,
3163*f5c631daSSadaf Ebrahimi const VRegister& vn,
3164*f5c631daSSadaf Ebrahimi const VRegister& vm,
3165*f5c631daSSadaf Ebrahimi int rot) {
3166*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3167*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3168*f5c631daSSadaf Ebrahimi fcmla(vd, vn, vm, rot);
3169*f5c631daSSadaf Ebrahimi }
Ins(const VRegister & vd,int vd_index,const VRegister & vn,int vn_index)3170*f5c631daSSadaf Ebrahimi void Ins(const VRegister& vd,
3171*f5c631daSSadaf Ebrahimi int vd_index,
3172*f5c631daSSadaf Ebrahimi const VRegister& vn,
3173*f5c631daSSadaf Ebrahimi int vn_index) {
3174*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3175*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3176*f5c631daSSadaf Ebrahimi ins(vd, vd_index, vn, vn_index);
3177*f5c631daSSadaf Ebrahimi }
Ins(const VRegister & vd,int vd_index,const Register & rn)3178*f5c631daSSadaf Ebrahimi void Ins(const VRegister& vd, int vd_index, const Register& rn) {
3179*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3180*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3181*f5c631daSSadaf Ebrahimi ins(vd, vd_index, rn);
3182*f5c631daSSadaf Ebrahimi }
Ld1(const VRegister & vt,const MemOperand & src)3183*f5c631daSSadaf Ebrahimi void Ld1(const VRegister& vt, const MemOperand& src) {
3184*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3185*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3186*f5c631daSSadaf Ebrahimi ld1(vt, src);
3187*f5c631daSSadaf Ebrahimi }
Ld1(const VRegister & vt,const VRegister & vt2,const MemOperand & src)3188*f5c631daSSadaf Ebrahimi void Ld1(const VRegister& vt, const VRegister& vt2, const MemOperand& src) {
3189*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3190*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3191*f5c631daSSadaf Ebrahimi ld1(vt, vt2, src);
3192*f5c631daSSadaf Ebrahimi }
Ld1(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const MemOperand & src)3193*f5c631daSSadaf Ebrahimi void Ld1(const VRegister& vt,
3194*f5c631daSSadaf Ebrahimi const VRegister& vt2,
3195*f5c631daSSadaf Ebrahimi const VRegister& vt3,
3196*f5c631daSSadaf Ebrahimi const MemOperand& src) {
3197*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3198*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3199*f5c631daSSadaf Ebrahimi ld1(vt, vt2, vt3, src);
3200*f5c631daSSadaf Ebrahimi }
Ld1(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const VRegister & vt4,const MemOperand & src)3201*f5c631daSSadaf Ebrahimi void Ld1(const VRegister& vt,
3202*f5c631daSSadaf Ebrahimi const VRegister& vt2,
3203*f5c631daSSadaf Ebrahimi const VRegister& vt3,
3204*f5c631daSSadaf Ebrahimi const VRegister& vt4,
3205*f5c631daSSadaf Ebrahimi const MemOperand& src) {
3206*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3207*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3208*f5c631daSSadaf Ebrahimi ld1(vt, vt2, vt3, vt4, src);
3209*f5c631daSSadaf Ebrahimi }
Ld1(const VRegister & vt,int lane,const MemOperand & src)3210*f5c631daSSadaf Ebrahimi void Ld1(const VRegister& vt, int lane, const MemOperand& src) {
3211*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3212*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3213*f5c631daSSadaf Ebrahimi ld1(vt, lane, src);
3214*f5c631daSSadaf Ebrahimi }
Ld1r(const VRegister & vt,const MemOperand & src)3215*f5c631daSSadaf Ebrahimi void Ld1r(const VRegister& vt, const MemOperand& src) {
3216*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3217*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3218*f5c631daSSadaf Ebrahimi ld1r(vt, src);
3219*f5c631daSSadaf Ebrahimi }
Ld2(const VRegister & vt,const VRegister & vt2,const MemOperand & src)3220*f5c631daSSadaf Ebrahimi void Ld2(const VRegister& vt, const VRegister& vt2, const MemOperand& src) {
3221*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3222*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3223*f5c631daSSadaf Ebrahimi ld2(vt, vt2, src);
3224*f5c631daSSadaf Ebrahimi }
Ld2(const VRegister & vt,const VRegister & vt2,int lane,const MemOperand & src)3225*f5c631daSSadaf Ebrahimi void Ld2(const VRegister& vt,
3226*f5c631daSSadaf Ebrahimi const VRegister& vt2,
3227*f5c631daSSadaf Ebrahimi int lane,
3228*f5c631daSSadaf Ebrahimi const MemOperand& src) {
3229*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3230*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3231*f5c631daSSadaf Ebrahimi ld2(vt, vt2, lane, src);
3232*f5c631daSSadaf Ebrahimi }
Ld2r(const VRegister & vt,const VRegister & vt2,const MemOperand & src)3233*f5c631daSSadaf Ebrahimi void Ld2r(const VRegister& vt, const VRegister& vt2, const MemOperand& src) {
3234*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3235*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3236*f5c631daSSadaf Ebrahimi ld2r(vt, vt2, src);
3237*f5c631daSSadaf Ebrahimi }
Ld3(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const MemOperand & src)3238*f5c631daSSadaf Ebrahimi void Ld3(const VRegister& vt,
3239*f5c631daSSadaf Ebrahimi const VRegister& vt2,
3240*f5c631daSSadaf Ebrahimi const VRegister& vt3,
3241*f5c631daSSadaf Ebrahimi const MemOperand& src) {
3242*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3243*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3244*f5c631daSSadaf Ebrahimi ld3(vt, vt2, vt3, src);
3245*f5c631daSSadaf Ebrahimi }
Ld3(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,int lane,const MemOperand & src)3246*f5c631daSSadaf Ebrahimi void Ld3(const VRegister& vt,
3247*f5c631daSSadaf Ebrahimi const VRegister& vt2,
3248*f5c631daSSadaf Ebrahimi const VRegister& vt3,
3249*f5c631daSSadaf Ebrahimi int lane,
3250*f5c631daSSadaf Ebrahimi const MemOperand& src) {
3251*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3252*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3253*f5c631daSSadaf Ebrahimi ld3(vt, vt2, vt3, lane, src);
3254*f5c631daSSadaf Ebrahimi }
Ld3r(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const MemOperand & src)3255*f5c631daSSadaf Ebrahimi void Ld3r(const VRegister& vt,
3256*f5c631daSSadaf Ebrahimi const VRegister& vt2,
3257*f5c631daSSadaf Ebrahimi const VRegister& vt3,
3258*f5c631daSSadaf Ebrahimi const MemOperand& src) {
3259*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3260*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3261*f5c631daSSadaf Ebrahimi ld3r(vt, vt2, vt3, src);
3262*f5c631daSSadaf Ebrahimi }
Ld4(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const VRegister & vt4,const MemOperand & src)3263*f5c631daSSadaf Ebrahimi void Ld4(const VRegister& vt,
3264*f5c631daSSadaf Ebrahimi const VRegister& vt2,
3265*f5c631daSSadaf Ebrahimi const VRegister& vt3,
3266*f5c631daSSadaf Ebrahimi const VRegister& vt4,
3267*f5c631daSSadaf Ebrahimi const MemOperand& src) {
3268*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3269*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3270*f5c631daSSadaf Ebrahimi ld4(vt, vt2, vt3, vt4, src);
3271*f5c631daSSadaf Ebrahimi }
Ld4(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const VRegister & vt4,int lane,const MemOperand & src)3272*f5c631daSSadaf Ebrahimi void Ld4(const VRegister& vt,
3273*f5c631daSSadaf Ebrahimi const VRegister& vt2,
3274*f5c631daSSadaf Ebrahimi const VRegister& vt3,
3275*f5c631daSSadaf Ebrahimi const VRegister& vt4,
3276*f5c631daSSadaf Ebrahimi int lane,
3277*f5c631daSSadaf Ebrahimi const MemOperand& src) {
3278*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3279*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3280*f5c631daSSadaf Ebrahimi ld4(vt, vt2, vt3, vt4, lane, src);
3281*f5c631daSSadaf Ebrahimi }
Ld4r(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const VRegister & vt4,const MemOperand & src)3282*f5c631daSSadaf Ebrahimi void Ld4r(const VRegister& vt,
3283*f5c631daSSadaf Ebrahimi const VRegister& vt2,
3284*f5c631daSSadaf Ebrahimi const VRegister& vt3,
3285*f5c631daSSadaf Ebrahimi const VRegister& vt4,
3286*f5c631daSSadaf Ebrahimi const MemOperand& src) {
3287*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3288*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3289*f5c631daSSadaf Ebrahimi ld4r(vt, vt2, vt3, vt4, src);
3290*f5c631daSSadaf Ebrahimi }
Mov(const VRegister & vd,int vd_index,const VRegister & vn,int vn_index)3291*f5c631daSSadaf Ebrahimi void Mov(const VRegister& vd,
3292*f5c631daSSadaf Ebrahimi int vd_index,
3293*f5c631daSSadaf Ebrahimi const VRegister& vn,
3294*f5c631daSSadaf Ebrahimi int vn_index) {
3295*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3296*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3297*f5c631daSSadaf Ebrahimi mov(vd, vd_index, vn, vn_index);
3298*f5c631daSSadaf Ebrahimi }
Mov(const VRegister & vd,const VRegister & vn,int index)3299*f5c631daSSadaf Ebrahimi void Mov(const VRegister& vd, const VRegister& vn, int index) {
3300*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3301*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3302*f5c631daSSadaf Ebrahimi mov(vd, vn, index);
3303*f5c631daSSadaf Ebrahimi }
Mov(const VRegister & vd,int vd_index,const Register & rn)3304*f5c631daSSadaf Ebrahimi void Mov(const VRegister& vd, int vd_index, const Register& rn) {
3305*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3306*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3307*f5c631daSSadaf Ebrahimi mov(vd, vd_index, rn);
3308*f5c631daSSadaf Ebrahimi }
Mov(const Register & rd,const VRegister & vn,int vn_index)3309*f5c631daSSadaf Ebrahimi void Mov(const Register& rd, const VRegister& vn, int vn_index) {
3310*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3311*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3312*f5c631daSSadaf Ebrahimi mov(rd, vn, vn_index);
3313*f5c631daSSadaf Ebrahimi }
3314*f5c631daSSadaf Ebrahimi void Movi(const VRegister& vd,
3315*f5c631daSSadaf Ebrahimi uint64_t imm,
3316*f5c631daSSadaf Ebrahimi Shift shift = LSL,
3317*f5c631daSSadaf Ebrahimi int shift_amount = 0);
3318*f5c631daSSadaf Ebrahimi void Movi(const VRegister& vd, uint64_t hi, uint64_t lo);
3319*f5c631daSSadaf Ebrahimi void Mvni(const VRegister& vd,
3320*f5c631daSSadaf Ebrahimi const int imm8,
3321*f5c631daSSadaf Ebrahimi Shift shift = LSL,
3322*f5c631daSSadaf Ebrahimi const int shift_amount = 0) {
3323*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3324*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3325*f5c631daSSadaf Ebrahimi mvni(vd, imm8, shift, shift_amount);
3326*f5c631daSSadaf Ebrahimi }
3327*f5c631daSSadaf Ebrahimi void Orr(const VRegister& vd, const int imm8, const int left_shift = 0) {
3328*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3329*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3330*f5c631daSSadaf Ebrahimi orr(vd, imm8, left_shift);
3331*f5c631daSSadaf Ebrahimi }
3332*f5c631daSSadaf Ebrahimi void Scvtf(const VRegister& vd, const VRegister& vn, int fbits = 0) {
3333*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3334*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3335*f5c631daSSadaf Ebrahimi scvtf(vd, vn, fbits);
3336*f5c631daSSadaf Ebrahimi }
3337*f5c631daSSadaf Ebrahimi void Ucvtf(const VRegister& vd, const VRegister& vn, int fbits = 0) {
3338*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3339*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3340*f5c631daSSadaf Ebrahimi ucvtf(vd, vn, fbits);
3341*f5c631daSSadaf Ebrahimi }
3342*f5c631daSSadaf Ebrahimi void Fcvtzs(const VRegister& vd, const VRegister& vn, int fbits = 0) {
3343*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3344*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3345*f5c631daSSadaf Ebrahimi fcvtzs(vd, vn, fbits);
3346*f5c631daSSadaf Ebrahimi }
3347*f5c631daSSadaf Ebrahimi void Fcvtzu(const VRegister& vd, const VRegister& vn, int fbits = 0) {
3348*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3349*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3350*f5c631daSSadaf Ebrahimi fcvtzu(vd, vn, fbits);
3351*f5c631daSSadaf Ebrahimi }
St1(const VRegister & vt,const MemOperand & dst)3352*f5c631daSSadaf Ebrahimi void St1(const VRegister& vt, const MemOperand& dst) {
3353*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3354*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3355*f5c631daSSadaf Ebrahimi st1(vt, dst);
3356*f5c631daSSadaf Ebrahimi }
St1(const VRegister & vt,const VRegister & vt2,const MemOperand & dst)3357*f5c631daSSadaf Ebrahimi void St1(const VRegister& vt, const VRegister& vt2, const MemOperand& dst) {
3358*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3359*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3360*f5c631daSSadaf Ebrahimi st1(vt, vt2, dst);
3361*f5c631daSSadaf Ebrahimi }
St1(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const MemOperand & dst)3362*f5c631daSSadaf Ebrahimi void St1(const VRegister& vt,
3363*f5c631daSSadaf Ebrahimi const VRegister& vt2,
3364*f5c631daSSadaf Ebrahimi const VRegister& vt3,
3365*f5c631daSSadaf Ebrahimi const MemOperand& dst) {
3366*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3367*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3368*f5c631daSSadaf Ebrahimi st1(vt, vt2, vt3, dst);
3369*f5c631daSSadaf Ebrahimi }
St1(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const VRegister & vt4,const MemOperand & dst)3370*f5c631daSSadaf Ebrahimi void St1(const VRegister& vt,
3371*f5c631daSSadaf Ebrahimi const VRegister& vt2,
3372*f5c631daSSadaf Ebrahimi const VRegister& vt3,
3373*f5c631daSSadaf Ebrahimi const VRegister& vt4,
3374*f5c631daSSadaf Ebrahimi const MemOperand& dst) {
3375*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3376*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3377*f5c631daSSadaf Ebrahimi st1(vt, vt2, vt3, vt4, dst);
3378*f5c631daSSadaf Ebrahimi }
St1(const VRegister & vt,int lane,const MemOperand & dst)3379*f5c631daSSadaf Ebrahimi void St1(const VRegister& vt, int lane, const MemOperand& dst) {
3380*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3381*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3382*f5c631daSSadaf Ebrahimi st1(vt, lane, dst);
3383*f5c631daSSadaf Ebrahimi }
St2(const VRegister & vt,const VRegister & vt2,const MemOperand & dst)3384*f5c631daSSadaf Ebrahimi void St2(const VRegister& vt, const VRegister& vt2, const MemOperand& dst) {
3385*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3386*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3387*f5c631daSSadaf Ebrahimi st2(vt, vt2, dst);
3388*f5c631daSSadaf Ebrahimi }
St3(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const MemOperand & dst)3389*f5c631daSSadaf Ebrahimi void St3(const VRegister& vt,
3390*f5c631daSSadaf Ebrahimi const VRegister& vt2,
3391*f5c631daSSadaf Ebrahimi const VRegister& vt3,
3392*f5c631daSSadaf Ebrahimi const MemOperand& dst) {
3393*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3394*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3395*f5c631daSSadaf Ebrahimi st3(vt, vt2, vt3, dst);
3396*f5c631daSSadaf Ebrahimi }
St4(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const VRegister & vt4,const MemOperand & dst)3397*f5c631daSSadaf Ebrahimi void St4(const VRegister& vt,
3398*f5c631daSSadaf Ebrahimi const VRegister& vt2,
3399*f5c631daSSadaf Ebrahimi const VRegister& vt3,
3400*f5c631daSSadaf Ebrahimi const VRegister& vt4,
3401*f5c631daSSadaf Ebrahimi const MemOperand& dst) {
3402*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3403*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3404*f5c631daSSadaf Ebrahimi st4(vt, vt2, vt3, vt4, dst);
3405*f5c631daSSadaf Ebrahimi }
St2(const VRegister & vt,const VRegister & vt2,int lane,const MemOperand & dst)3406*f5c631daSSadaf Ebrahimi void St2(const VRegister& vt,
3407*f5c631daSSadaf Ebrahimi const VRegister& vt2,
3408*f5c631daSSadaf Ebrahimi int lane,
3409*f5c631daSSadaf Ebrahimi const MemOperand& dst) {
3410*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3411*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3412*f5c631daSSadaf Ebrahimi st2(vt, vt2, lane, dst);
3413*f5c631daSSadaf Ebrahimi }
St3(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,int lane,const MemOperand & dst)3414*f5c631daSSadaf Ebrahimi void St3(const VRegister& vt,
3415*f5c631daSSadaf Ebrahimi const VRegister& vt2,
3416*f5c631daSSadaf Ebrahimi const VRegister& vt3,
3417*f5c631daSSadaf Ebrahimi int lane,
3418*f5c631daSSadaf Ebrahimi const MemOperand& dst) {
3419*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3420*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3421*f5c631daSSadaf Ebrahimi st3(vt, vt2, vt3, lane, dst);
3422*f5c631daSSadaf Ebrahimi }
St4(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const VRegister & vt4,int lane,const MemOperand & dst)3423*f5c631daSSadaf Ebrahimi void St4(const VRegister& vt,
3424*f5c631daSSadaf Ebrahimi const VRegister& vt2,
3425*f5c631daSSadaf Ebrahimi const VRegister& vt3,
3426*f5c631daSSadaf Ebrahimi const VRegister& vt4,
3427*f5c631daSSadaf Ebrahimi int lane,
3428*f5c631daSSadaf Ebrahimi const MemOperand& dst) {
3429*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3430*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3431*f5c631daSSadaf Ebrahimi st4(vt, vt2, vt3, vt4, lane, dst);
3432*f5c631daSSadaf Ebrahimi }
Smov(const Register & rd,const VRegister & vn,int vn_index)3433*f5c631daSSadaf Ebrahimi void Smov(const Register& rd, const VRegister& vn, int vn_index) {
3434*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3435*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3436*f5c631daSSadaf Ebrahimi smov(rd, vn, vn_index);
3437*f5c631daSSadaf Ebrahimi }
Umov(const Register & rd,const VRegister & vn,int vn_index)3438*f5c631daSSadaf Ebrahimi void Umov(const Register& rd, const VRegister& vn, int vn_index) {
3439*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3440*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3441*f5c631daSSadaf Ebrahimi umov(rd, vn, vn_index);
3442*f5c631daSSadaf Ebrahimi }
Crc32b(const Register & rd,const Register & rn,const Register & rm)3443*f5c631daSSadaf Ebrahimi void Crc32b(const Register& rd, const Register& rn, const Register& rm) {
3444*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3445*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3446*f5c631daSSadaf Ebrahimi crc32b(rd, rn, rm);
3447*f5c631daSSadaf Ebrahimi }
Crc32h(const Register & rd,const Register & rn,const Register & rm)3448*f5c631daSSadaf Ebrahimi void Crc32h(const Register& rd, const Register& rn, const Register& rm) {
3449*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3450*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3451*f5c631daSSadaf Ebrahimi crc32h(rd, rn, rm);
3452*f5c631daSSadaf Ebrahimi }
Crc32w(const Register & rd,const Register & rn,const Register & rm)3453*f5c631daSSadaf Ebrahimi void Crc32w(const Register& rd, const Register& rn, const Register& rm) {
3454*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3455*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3456*f5c631daSSadaf Ebrahimi crc32w(rd, rn, rm);
3457*f5c631daSSadaf Ebrahimi }
Crc32x(const Register & rd,const Register & rn,const Register & rm)3458*f5c631daSSadaf Ebrahimi void Crc32x(const Register& rd, const Register& rn, const Register& rm) {
3459*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3460*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3461*f5c631daSSadaf Ebrahimi crc32x(rd, rn, rm);
3462*f5c631daSSadaf Ebrahimi }
Crc32cb(const Register & rd,const Register & rn,const Register & rm)3463*f5c631daSSadaf Ebrahimi void Crc32cb(const Register& rd, const Register& rn, const Register& rm) {
3464*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3465*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3466*f5c631daSSadaf Ebrahimi crc32cb(rd, rn, rm);
3467*f5c631daSSadaf Ebrahimi }
Crc32ch(const Register & rd,const Register & rn,const Register & rm)3468*f5c631daSSadaf Ebrahimi void Crc32ch(const Register& rd, const Register& rn, const Register& rm) {
3469*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3470*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3471*f5c631daSSadaf Ebrahimi crc32ch(rd, rn, rm);
3472*f5c631daSSadaf Ebrahimi }
Crc32cw(const Register & rd,const Register & rn,const Register & rm)3473*f5c631daSSadaf Ebrahimi void Crc32cw(const Register& rd, const Register& rn, const Register& rm) {
3474*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3475*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3476*f5c631daSSadaf Ebrahimi crc32cw(rd, rn, rm);
3477*f5c631daSSadaf Ebrahimi }
Crc32cx(const Register & rd,const Register & rn,const Register & rm)3478*f5c631daSSadaf Ebrahimi void Crc32cx(const Register& rd, const Register& rn, const Register& rm) {
3479*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3480*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3481*f5c631daSSadaf Ebrahimi crc32cx(rd, rn, rm);
3482*f5c631daSSadaf Ebrahimi }
3483*f5c631daSSadaf Ebrahimi
3484*f5c631daSSadaf Ebrahimi // Scalable Vector Extensions.
Abs(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)3485*f5c631daSSadaf Ebrahimi void Abs(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
3486*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3487*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3488*f5c631daSSadaf Ebrahimi abs(zd, pg, zn);
3489*f5c631daSSadaf Ebrahimi }
Add(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)3490*f5c631daSSadaf Ebrahimi void Add(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
3491*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3492*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3493*f5c631daSSadaf Ebrahimi add(zd, zn, zm);
3494*f5c631daSSadaf Ebrahimi }
Add(const ZRegister & zd,const ZRegister & zn,IntegerOperand imm)3495*f5c631daSSadaf Ebrahimi void Add(const ZRegister& zd, const ZRegister& zn, IntegerOperand imm) {
3496*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3497*f5c631daSSadaf Ebrahimi AddSubHelper(kAddImmediate, zd, zn, imm);
3498*f5c631daSSadaf Ebrahimi }
3499*f5c631daSSadaf Ebrahimi void Addpl(const Register& xd, const Register& xn, int64_t multiplier);
3500*f5c631daSSadaf Ebrahimi void Addvl(const Register& xd, const Register& xn, int64_t multiplier);
3501*f5c631daSSadaf Ebrahimi // Note that unlike the core ISA, SVE's `adr` is not PC-relative.
Adr(const ZRegister & zd,const SVEMemOperand & addr)3502*f5c631daSSadaf Ebrahimi void Adr(const ZRegister& zd, const SVEMemOperand& addr) {
3503*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3504*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3505*f5c631daSSadaf Ebrahimi adr(zd, addr);
3506*f5c631daSSadaf Ebrahimi }
And(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)3507*f5c631daSSadaf Ebrahimi void And(const PRegisterWithLaneSize& pd,
3508*f5c631daSSadaf Ebrahimi const PRegisterZ& pg,
3509*f5c631daSSadaf Ebrahimi const PRegisterWithLaneSize& pn,
3510*f5c631daSSadaf Ebrahimi const PRegisterWithLaneSize& pm) {
3511*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3512*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3513*f5c631daSSadaf Ebrahimi and_(pd, pg, pn, pm);
3514*f5c631daSSadaf Ebrahimi }
And(const ZRegister & zd,const ZRegister & zn,uint64_t imm)3515*f5c631daSSadaf Ebrahimi void And(const ZRegister& zd, const ZRegister& zn, uint64_t imm) {
3516*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3517*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3518*f5c631daSSadaf Ebrahimi if (IsImmLogical(imm, zd.GetLaneSizeInBits())) {
3519*f5c631daSSadaf Ebrahimi and_(zd, zn, imm);
3520*f5c631daSSadaf Ebrahimi } else {
3521*f5c631daSSadaf Ebrahimi // TODO: Synthesise the immediate once 'Mov' is implemented.
3522*f5c631daSSadaf Ebrahimi VIXL_UNIMPLEMENTED();
3523*f5c631daSSadaf Ebrahimi }
3524*f5c631daSSadaf Ebrahimi }
And(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)3525*f5c631daSSadaf Ebrahimi void And(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
3526*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3527*f5c631daSSadaf Ebrahimi VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
3528*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3529*f5c631daSSadaf Ebrahimi and_(zd.VnD(), zn.VnD(), zm.VnD());
3530*f5c631daSSadaf Ebrahimi }
Ands(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)3531*f5c631daSSadaf Ebrahimi void Ands(const PRegisterWithLaneSize& pd,
3532*f5c631daSSadaf Ebrahimi const PRegisterZ& pg,
3533*f5c631daSSadaf Ebrahimi const PRegisterWithLaneSize& pn,
3534*f5c631daSSadaf Ebrahimi const PRegisterWithLaneSize& pm) {
3535*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3536*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3537*f5c631daSSadaf Ebrahimi ands(pd, pg, pn, pm);
3538*f5c631daSSadaf Ebrahimi }
Andv(const VRegister & vd,const PRegister & pg,const ZRegister & zn)3539*f5c631daSSadaf Ebrahimi void Andv(const VRegister& vd, const PRegister& pg, const ZRegister& zn) {
3540*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3541*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3542*f5c631daSSadaf Ebrahimi andv(vd, pg, zn);
3543*f5c631daSSadaf Ebrahimi }
Asr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,int shift)3544*f5c631daSSadaf Ebrahimi void Asr(const ZRegister& zd,
3545*f5c631daSSadaf Ebrahimi const PRegisterM& pg,
3546*f5c631daSSadaf Ebrahimi const ZRegister& zn,
3547*f5c631daSSadaf Ebrahimi int shift) {
3548*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3549*f5c631daSSadaf Ebrahimi MovprfxHelperScope guard(this, zd, pg, zn);
3550*f5c631daSSadaf Ebrahimi asr(zd, pg, zd, shift);
3551*f5c631daSSadaf Ebrahimi }
3552*f5c631daSSadaf Ebrahimi void Asr(const ZRegister& zd,
3553*f5c631daSSadaf Ebrahimi const PRegisterM& pg,
3554*f5c631daSSadaf Ebrahimi const ZRegister& zn,
3555*f5c631daSSadaf Ebrahimi const ZRegister& zm);
Asr(const ZRegister & zd,const ZRegister & zn,int shift)3556*f5c631daSSadaf Ebrahimi void Asr(const ZRegister& zd, const ZRegister& zn, int shift) {
3557*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3558*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3559*f5c631daSSadaf Ebrahimi asr(zd, zn, shift);
3560*f5c631daSSadaf Ebrahimi }
Asr(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)3561*f5c631daSSadaf Ebrahimi void Asr(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
3562*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3563*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3564*f5c631daSSadaf Ebrahimi asr(zd, zn, zm);
3565*f5c631daSSadaf Ebrahimi }
Asrd(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,int shift)3566*f5c631daSSadaf Ebrahimi void Asrd(const ZRegister& zd,
3567*f5c631daSSadaf Ebrahimi const PRegisterM& pg,
3568*f5c631daSSadaf Ebrahimi const ZRegister& zn,
3569*f5c631daSSadaf Ebrahimi int shift) {
3570*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3571*f5c631daSSadaf Ebrahimi MovprfxHelperScope guard(this, zd, pg, zn);
3572*f5c631daSSadaf Ebrahimi asrd(zd, pg, zd, shift);
3573*f5c631daSSadaf Ebrahimi }
Bic(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)3574*f5c631daSSadaf Ebrahimi void Bic(const PRegisterWithLaneSize& pd,
3575*f5c631daSSadaf Ebrahimi const PRegisterZ& pg,
3576*f5c631daSSadaf Ebrahimi const PRegisterWithLaneSize& pn,
3577*f5c631daSSadaf Ebrahimi const PRegisterWithLaneSize& pm) {
3578*f5c631daSSadaf Ebrahimi VIXL_ASSERT(allow_macro_instructions_);
3579*f5c631daSSadaf Ebrahimi SingleEmissionCheckScope guard(this);
3580*f5c631daSSadaf Ebrahimi bic(pd, pg, pn, pm);
3581*f5c631daSSadaf Ebrahimi }
Bic(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)3582