xref: /aosp_15_r20/external/vixl/src/aarch64/assembler-aarch64.h (revision f5c631da2f1efdd72b5fd1e20510e4042af13d77)
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_ASSEMBLER_AARCH64_H_
28*f5c631daSSadaf Ebrahimi #define VIXL_AARCH64_ASSEMBLER_AARCH64_H_
29*f5c631daSSadaf Ebrahimi 
30*f5c631daSSadaf Ebrahimi #include "../assembler-base-vixl.h"
31*f5c631daSSadaf Ebrahimi #include "../code-generation-scopes-vixl.h"
32*f5c631daSSadaf Ebrahimi #include "../cpu-features.h"
33*f5c631daSSadaf Ebrahimi #include "../globals-vixl.h"
34*f5c631daSSadaf Ebrahimi #include "../invalset-vixl.h"
35*f5c631daSSadaf Ebrahimi #include "../utils-vixl.h"
36*f5c631daSSadaf Ebrahimi #include "operands-aarch64.h"
37*f5c631daSSadaf Ebrahimi 
38*f5c631daSSadaf Ebrahimi namespace vixl {
39*f5c631daSSadaf Ebrahimi namespace aarch64 {
40*f5c631daSSadaf Ebrahimi 
41*f5c631daSSadaf Ebrahimi class LabelTestHelper;  // Forward declaration.
42*f5c631daSSadaf Ebrahimi 
43*f5c631daSSadaf Ebrahimi 
44*f5c631daSSadaf Ebrahimi class Label {
45*f5c631daSSadaf Ebrahimi  public:
Label()46*f5c631daSSadaf Ebrahimi   Label() : location_(kLocationUnbound) {}
~Label()47*f5c631daSSadaf Ebrahimi   ~Label() {
48*f5c631daSSadaf Ebrahimi     // All links to a label must have been resolved before it is destructed.
49*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(!IsLinked());
50*f5c631daSSadaf Ebrahimi   }
51*f5c631daSSadaf Ebrahimi 
IsBound()52*f5c631daSSadaf Ebrahimi   bool IsBound() const { return location_ >= 0; }
IsLinked()53*f5c631daSSadaf Ebrahimi   bool IsLinked() const { return !links_.empty(); }
54*f5c631daSSadaf Ebrahimi 
GetLocation()55*f5c631daSSadaf Ebrahimi   ptrdiff_t GetLocation() const { return location_; }
56*f5c631daSSadaf Ebrahimi   VIXL_DEPRECATED("GetLocation", ptrdiff_t location() const) {
57*f5c631daSSadaf Ebrahimi     return GetLocation();
58*f5c631daSSadaf Ebrahimi   }
59*f5c631daSSadaf Ebrahimi 
60*f5c631daSSadaf Ebrahimi   static const int kNPreallocatedLinks = 4;
61*f5c631daSSadaf Ebrahimi   static const ptrdiff_t kInvalidLinkKey = PTRDIFF_MAX;
62*f5c631daSSadaf Ebrahimi   static const size_t kReclaimFrom = 512;
63*f5c631daSSadaf Ebrahimi   static const size_t kReclaimFactor = 2;
64*f5c631daSSadaf Ebrahimi 
65*f5c631daSSadaf Ebrahimi   typedef InvalSet<ptrdiff_t,
66*f5c631daSSadaf Ebrahimi                    kNPreallocatedLinks,
67*f5c631daSSadaf Ebrahimi                    ptrdiff_t,
68*f5c631daSSadaf Ebrahimi                    kInvalidLinkKey,
69*f5c631daSSadaf Ebrahimi                    kReclaimFrom,
70*f5c631daSSadaf Ebrahimi                    kReclaimFactor>
71*f5c631daSSadaf Ebrahimi       LinksSetBase;
72*f5c631daSSadaf Ebrahimi   typedef InvalSetIterator<LinksSetBase> LabelLinksIteratorBase;
73*f5c631daSSadaf Ebrahimi 
74*f5c631daSSadaf Ebrahimi  private:
75*f5c631daSSadaf Ebrahimi   class LinksSet : public LinksSetBase {
76*f5c631daSSadaf Ebrahimi    public:
LinksSet()77*f5c631daSSadaf Ebrahimi     LinksSet() : LinksSetBase() {}
78*f5c631daSSadaf Ebrahimi   };
79*f5c631daSSadaf Ebrahimi 
80*f5c631daSSadaf Ebrahimi   // Allows iterating over the links of a label. The behaviour is undefined if
81*f5c631daSSadaf Ebrahimi   // the list of links is modified in any way while iterating.
82*f5c631daSSadaf Ebrahimi   class LabelLinksIterator : public LabelLinksIteratorBase {
83*f5c631daSSadaf Ebrahimi    public:
LabelLinksIterator(Label * label)84*f5c631daSSadaf Ebrahimi     explicit LabelLinksIterator(Label* label)
85*f5c631daSSadaf Ebrahimi         : LabelLinksIteratorBase(&label->links_) {}
86*f5c631daSSadaf Ebrahimi 
87*f5c631daSSadaf Ebrahimi     // TODO: Remove these and use the STL-like interface instead.
88*f5c631daSSadaf Ebrahimi     using LabelLinksIteratorBase::Advance;
89*f5c631daSSadaf Ebrahimi     using LabelLinksIteratorBase::Current;
90*f5c631daSSadaf Ebrahimi   };
91*f5c631daSSadaf Ebrahimi 
Bind(ptrdiff_t location)92*f5c631daSSadaf Ebrahimi   void Bind(ptrdiff_t location) {
93*f5c631daSSadaf Ebrahimi     // Labels can only be bound once.
94*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(!IsBound());
95*f5c631daSSadaf Ebrahimi     location_ = location;
96*f5c631daSSadaf Ebrahimi   }
97*f5c631daSSadaf Ebrahimi 
AddLink(ptrdiff_t instruction)98*f5c631daSSadaf Ebrahimi   void AddLink(ptrdiff_t instruction) {
99*f5c631daSSadaf Ebrahimi     // If a label is bound, the assembler already has the information it needs
100*f5c631daSSadaf Ebrahimi     // to write the instruction, so there is no need to add it to links_.
101*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(!IsBound());
102*f5c631daSSadaf Ebrahimi     links_.insert(instruction);
103*f5c631daSSadaf Ebrahimi   }
104*f5c631daSSadaf Ebrahimi 
DeleteLink(ptrdiff_t instruction)105*f5c631daSSadaf Ebrahimi   void DeleteLink(ptrdiff_t instruction) { links_.erase(instruction); }
106*f5c631daSSadaf Ebrahimi 
ClearAllLinks()107*f5c631daSSadaf Ebrahimi   void ClearAllLinks() { links_.clear(); }
108*f5c631daSSadaf Ebrahimi 
109*f5c631daSSadaf Ebrahimi   // TODO: The comment below considers average case complexity for our
110*f5c631daSSadaf Ebrahimi   // usual use-cases. The elements of interest are:
111*f5c631daSSadaf Ebrahimi   // - Branches to a label are emitted in order: branch instructions to a label
112*f5c631daSSadaf Ebrahimi   // are generated at an offset in the code generation buffer greater than any
113*f5c631daSSadaf Ebrahimi   // other branch to that same label already generated. As an example, this can
114*f5c631daSSadaf Ebrahimi   // be broken when an instruction is patched to become a branch. Note that the
115*f5c631daSSadaf Ebrahimi   // code will still work, but the complexity considerations below may locally
116*f5c631daSSadaf Ebrahimi   // not apply any more.
117*f5c631daSSadaf Ebrahimi   // - Veneers are generated in order: for multiple branches of the same type
118*f5c631daSSadaf Ebrahimi   // branching to the same unbound label going out of range, veneers are
119*f5c631daSSadaf Ebrahimi   // generated in growing order of the branch instruction offset from the start
120*f5c631daSSadaf Ebrahimi   // of the buffer.
121*f5c631daSSadaf Ebrahimi   //
122*f5c631daSSadaf Ebrahimi   // When creating a veneer for a branch going out of range, the link for this
123*f5c631daSSadaf Ebrahimi   // branch needs to be removed from this `links_`. Since all branches are
124*f5c631daSSadaf Ebrahimi   // tracked in one underlying InvalSet, the complexity for this deletion is the
125*f5c631daSSadaf Ebrahimi   // same as for finding the element, ie. O(n), where n is the number of links
126*f5c631daSSadaf Ebrahimi   // in the set.
127*f5c631daSSadaf Ebrahimi   // This could be reduced to O(1) by using the same trick as used when tracking
128*f5c631daSSadaf Ebrahimi   // branch information for veneers: split the container to use one set per type
129*f5c631daSSadaf Ebrahimi   // of branch. With that setup, when a veneer is created and the link needs to
130*f5c631daSSadaf Ebrahimi   // be deleted, if the two points above hold, it must be the minimum element of
131*f5c631daSSadaf Ebrahimi   // the set for its type of branch, and that minimum element will be accessible
132*f5c631daSSadaf Ebrahimi   // in O(1).
133*f5c631daSSadaf Ebrahimi 
134*f5c631daSSadaf Ebrahimi   // The offsets of the instructions that have linked to this label.
135*f5c631daSSadaf Ebrahimi   LinksSet links_;
136*f5c631daSSadaf Ebrahimi   // The label location.
137*f5c631daSSadaf Ebrahimi   ptrdiff_t location_;
138*f5c631daSSadaf Ebrahimi 
139*f5c631daSSadaf Ebrahimi   static const ptrdiff_t kLocationUnbound = -1;
140*f5c631daSSadaf Ebrahimi 
141*f5c631daSSadaf Ebrahimi // It is not safe to copy labels, so disable the copy constructor and operator
142*f5c631daSSadaf Ebrahimi // by declaring them private (without an implementation).
143*f5c631daSSadaf Ebrahimi #if __cplusplus >= 201103L
144*f5c631daSSadaf Ebrahimi   Label(const Label&) = delete;
145*f5c631daSSadaf Ebrahimi   void operator=(const Label&) = delete;
146*f5c631daSSadaf Ebrahimi #else
147*f5c631daSSadaf Ebrahimi   Label(const Label&);
148*f5c631daSSadaf Ebrahimi   void operator=(const Label&);
149*f5c631daSSadaf Ebrahimi #endif
150*f5c631daSSadaf Ebrahimi 
151*f5c631daSSadaf Ebrahimi   // The Assembler class is responsible for binding and linking labels, since
152*f5c631daSSadaf Ebrahimi   // the stored offsets need to be consistent with the Assembler's buffer.
153*f5c631daSSadaf Ebrahimi   friend class Assembler;
154*f5c631daSSadaf Ebrahimi   // The MacroAssembler and VeneerPool handle resolution of branches to distant
155*f5c631daSSadaf Ebrahimi   // targets.
156*f5c631daSSadaf Ebrahimi   friend class MacroAssembler;
157*f5c631daSSadaf Ebrahimi   friend class VeneerPool;
158*f5c631daSSadaf Ebrahimi };
159*f5c631daSSadaf Ebrahimi 
160*f5c631daSSadaf Ebrahimi 
161*f5c631daSSadaf Ebrahimi class Assembler;
162*f5c631daSSadaf Ebrahimi class LiteralPool;
163*f5c631daSSadaf Ebrahimi 
164*f5c631daSSadaf Ebrahimi // A literal is a 32-bit or 64-bit piece of data stored in the instruction
165*f5c631daSSadaf Ebrahimi // stream and loaded through a pc relative load. The same literal can be
166*f5c631daSSadaf Ebrahimi // referred to by multiple instructions but a literal can only reside at one
167*f5c631daSSadaf Ebrahimi // place in memory. A literal can be used by a load before or after being
168*f5c631daSSadaf Ebrahimi // placed in memory.
169*f5c631daSSadaf Ebrahimi //
170*f5c631daSSadaf Ebrahimi // Internally an offset of 0 is associated with a literal which has been
171*f5c631daSSadaf Ebrahimi // neither used nor placed. Then two possibilities arise:
172*f5c631daSSadaf Ebrahimi //  1) the label is placed, the offset (stored as offset + 1) is used to
173*f5c631daSSadaf Ebrahimi //     resolve any subsequent load using the label.
174*f5c631daSSadaf Ebrahimi //  2) the label is not placed and offset is the offset of the last load using
175*f5c631daSSadaf Ebrahimi //     the literal (stored as -offset -1). If multiple loads refer to this
176*f5c631daSSadaf Ebrahimi //     literal then the last load holds the offset of the preceding load and
177*f5c631daSSadaf Ebrahimi //     all loads form a chain. Once the offset is placed all the loads in the
178*f5c631daSSadaf Ebrahimi //     chain are resolved and future loads fall back to possibility 1.
179*f5c631daSSadaf Ebrahimi class RawLiteral {
180*f5c631daSSadaf Ebrahimi  public:
181*f5c631daSSadaf Ebrahimi   enum DeletionPolicy {
182*f5c631daSSadaf Ebrahimi     kDeletedOnPlacementByPool,
183*f5c631daSSadaf Ebrahimi     kDeletedOnPoolDestruction,
184*f5c631daSSadaf Ebrahimi     kManuallyDeleted
185*f5c631daSSadaf Ebrahimi   };
186*f5c631daSSadaf Ebrahimi 
187*f5c631daSSadaf Ebrahimi   RawLiteral(size_t size,
188*f5c631daSSadaf Ebrahimi              LiteralPool* literal_pool,
189*f5c631daSSadaf Ebrahimi              DeletionPolicy deletion_policy = kManuallyDeleted);
190*f5c631daSSadaf Ebrahimi 
191*f5c631daSSadaf Ebrahimi   // The literal pool only sees and deletes `RawLiteral*` pointers, but they are
192*f5c631daSSadaf Ebrahimi   // actually pointing to `Literal<T>` objects.
~RawLiteral()193*f5c631daSSadaf Ebrahimi   virtual ~RawLiteral() {}
194*f5c631daSSadaf Ebrahimi 
GetSize()195*f5c631daSSadaf Ebrahimi   size_t GetSize() const {
196*f5c631daSSadaf Ebrahimi     VIXL_STATIC_ASSERT(kDRegSizeInBytes == kXRegSizeInBytes);
197*f5c631daSSadaf Ebrahimi     VIXL_STATIC_ASSERT(kSRegSizeInBytes == kWRegSizeInBytes);
198*f5c631daSSadaf Ebrahimi     VIXL_ASSERT((size_ == kXRegSizeInBytes) || (size_ == kWRegSizeInBytes) ||
199*f5c631daSSadaf Ebrahimi                 (size_ == kQRegSizeInBytes));
200*f5c631daSSadaf Ebrahimi     return size_;
201*f5c631daSSadaf Ebrahimi   }
202*f5c631daSSadaf Ebrahimi   VIXL_DEPRECATED("GetSize", size_t size()) { return GetSize(); }
203*f5c631daSSadaf Ebrahimi 
GetRawValue128Low64()204*f5c631daSSadaf Ebrahimi   uint64_t GetRawValue128Low64() const {
205*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(size_ == kQRegSizeInBytes);
206*f5c631daSSadaf Ebrahimi     return low64_;
207*f5c631daSSadaf Ebrahimi   }
208*f5c631daSSadaf Ebrahimi   VIXL_DEPRECATED("GetRawValue128Low64", uint64_t raw_value128_low64()) {
209*f5c631daSSadaf Ebrahimi     return GetRawValue128Low64();
210*f5c631daSSadaf Ebrahimi   }
211*f5c631daSSadaf Ebrahimi 
GetRawValue128High64()212*f5c631daSSadaf Ebrahimi   uint64_t GetRawValue128High64() const {
213*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(size_ == kQRegSizeInBytes);
214*f5c631daSSadaf Ebrahimi     return high64_;
215*f5c631daSSadaf Ebrahimi   }
216*f5c631daSSadaf Ebrahimi   VIXL_DEPRECATED("GetRawValue128High64", uint64_t raw_value128_high64()) {
217*f5c631daSSadaf Ebrahimi     return GetRawValue128High64();
218*f5c631daSSadaf Ebrahimi   }
219*f5c631daSSadaf Ebrahimi 
GetRawValue64()220*f5c631daSSadaf Ebrahimi   uint64_t GetRawValue64() const {
221*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(size_ == kXRegSizeInBytes);
222*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(high64_ == 0);
223*f5c631daSSadaf Ebrahimi     return low64_;
224*f5c631daSSadaf Ebrahimi   }
225*f5c631daSSadaf Ebrahimi   VIXL_DEPRECATED("GetRawValue64", uint64_t raw_value64()) {
226*f5c631daSSadaf Ebrahimi     return GetRawValue64();
227*f5c631daSSadaf Ebrahimi   }
228*f5c631daSSadaf Ebrahimi 
GetRawValue32()229*f5c631daSSadaf Ebrahimi   uint32_t GetRawValue32() const {
230*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(size_ == kWRegSizeInBytes);
231*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(high64_ == 0);
232*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint32(low64_) || IsInt32(low64_));
233*f5c631daSSadaf Ebrahimi     return static_cast<uint32_t>(low64_);
234*f5c631daSSadaf Ebrahimi   }
235*f5c631daSSadaf Ebrahimi   VIXL_DEPRECATED("GetRawValue32", uint32_t raw_value32()) {
236*f5c631daSSadaf Ebrahimi     return GetRawValue32();
237*f5c631daSSadaf Ebrahimi   }
238*f5c631daSSadaf Ebrahimi 
IsUsed()239*f5c631daSSadaf Ebrahimi   bool IsUsed() const { return offset_ < 0; }
IsPlaced()240*f5c631daSSadaf Ebrahimi   bool IsPlaced() const { return offset_ > 0; }
241*f5c631daSSadaf Ebrahimi 
GetLiteralPool()242*f5c631daSSadaf Ebrahimi   LiteralPool* GetLiteralPool() const { return literal_pool_; }
243*f5c631daSSadaf Ebrahimi 
GetOffset()244*f5c631daSSadaf Ebrahimi   ptrdiff_t GetOffset() const {
245*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsPlaced());
246*f5c631daSSadaf Ebrahimi     return offset_ - 1;
247*f5c631daSSadaf Ebrahimi   }
248*f5c631daSSadaf Ebrahimi   VIXL_DEPRECATED("GetOffset", ptrdiff_t offset()) { return GetOffset(); }
249*f5c631daSSadaf Ebrahimi 
250*f5c631daSSadaf Ebrahimi  protected:
SetOffset(ptrdiff_t offset)251*f5c631daSSadaf Ebrahimi   void SetOffset(ptrdiff_t offset) {
252*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(offset >= 0);
253*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsWordAligned(offset));
254*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(!IsPlaced());
255*f5c631daSSadaf Ebrahimi     offset_ = offset + 1;
256*f5c631daSSadaf Ebrahimi   }
set_offset(ptrdiff_t offset)257*f5c631daSSadaf Ebrahimi   VIXL_DEPRECATED("SetOffset", void set_offset(ptrdiff_t offset)) {
258*f5c631daSSadaf Ebrahimi     SetOffset(offset);
259*f5c631daSSadaf Ebrahimi   }
260*f5c631daSSadaf Ebrahimi 
GetLastUse()261*f5c631daSSadaf Ebrahimi   ptrdiff_t GetLastUse() const {
262*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUsed());
263*f5c631daSSadaf Ebrahimi     return -offset_ - 1;
264*f5c631daSSadaf Ebrahimi   }
265*f5c631daSSadaf Ebrahimi   VIXL_DEPRECATED("GetLastUse", ptrdiff_t last_use()) { return GetLastUse(); }
266*f5c631daSSadaf Ebrahimi 
SetLastUse(ptrdiff_t offset)267*f5c631daSSadaf Ebrahimi   void SetLastUse(ptrdiff_t offset) {
268*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(offset >= 0);
269*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsWordAligned(offset));
270*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(!IsPlaced());
271*f5c631daSSadaf Ebrahimi     offset_ = -offset - 1;
272*f5c631daSSadaf Ebrahimi   }
set_last_use(ptrdiff_t offset)273*f5c631daSSadaf Ebrahimi   VIXL_DEPRECATED("SetLastUse", void set_last_use(ptrdiff_t offset)) {
274*f5c631daSSadaf Ebrahimi     SetLastUse(offset);
275*f5c631daSSadaf Ebrahimi   }
276*f5c631daSSadaf Ebrahimi 
277*f5c631daSSadaf Ebrahimi   size_t size_;
278*f5c631daSSadaf Ebrahimi   ptrdiff_t offset_;
279*f5c631daSSadaf Ebrahimi   uint64_t low64_;
280*f5c631daSSadaf Ebrahimi   uint64_t high64_;
281*f5c631daSSadaf Ebrahimi 
282*f5c631daSSadaf Ebrahimi  private:
283*f5c631daSSadaf Ebrahimi   LiteralPool* literal_pool_;
284*f5c631daSSadaf Ebrahimi   DeletionPolicy deletion_policy_;
285*f5c631daSSadaf Ebrahimi 
286*f5c631daSSadaf Ebrahimi   friend class Assembler;
287*f5c631daSSadaf Ebrahimi   friend class LiteralPool;
288*f5c631daSSadaf Ebrahimi };
289*f5c631daSSadaf Ebrahimi 
290*f5c631daSSadaf Ebrahimi 
291*f5c631daSSadaf Ebrahimi template <typename T>
292*f5c631daSSadaf Ebrahimi class Literal : public RawLiteral {
293*f5c631daSSadaf Ebrahimi  public:
294*f5c631daSSadaf Ebrahimi   explicit Literal(T value,
295*f5c631daSSadaf Ebrahimi                    LiteralPool* literal_pool = NULL,
296*f5c631daSSadaf Ebrahimi                    RawLiteral::DeletionPolicy ownership = kManuallyDeleted)
RawLiteral(sizeof (value),literal_pool,ownership)297*f5c631daSSadaf Ebrahimi       : RawLiteral(sizeof(value), literal_pool, ownership) {
298*f5c631daSSadaf Ebrahimi     VIXL_STATIC_ASSERT(sizeof(value) <= kXRegSizeInBytes);
299*f5c631daSSadaf Ebrahimi     UpdateValue(value);
300*f5c631daSSadaf Ebrahimi   }
301*f5c631daSSadaf Ebrahimi 
302*f5c631daSSadaf Ebrahimi   Literal(T high64,
303*f5c631daSSadaf Ebrahimi           T low64,
304*f5c631daSSadaf Ebrahimi           LiteralPool* literal_pool = NULL,
305*f5c631daSSadaf Ebrahimi           RawLiteral::DeletionPolicy ownership = kManuallyDeleted)
RawLiteral(kQRegSizeInBytes,literal_pool,ownership)306*f5c631daSSadaf Ebrahimi       : RawLiteral(kQRegSizeInBytes, literal_pool, ownership) {
307*f5c631daSSadaf Ebrahimi     VIXL_STATIC_ASSERT(sizeof(low64) == (kQRegSizeInBytes / 2));
308*f5c631daSSadaf Ebrahimi     UpdateValue(high64, low64);
309*f5c631daSSadaf Ebrahimi   }
310*f5c631daSSadaf Ebrahimi 
~Literal()311*f5c631daSSadaf Ebrahimi   virtual ~Literal() {}
312*f5c631daSSadaf Ebrahimi 
313*f5c631daSSadaf Ebrahimi   // Update the value of this literal, if necessary by rewriting the value in
314*f5c631daSSadaf Ebrahimi   // the pool.
315*f5c631daSSadaf Ebrahimi   // If the literal has already been placed in a literal pool, the address of
316*f5c631daSSadaf Ebrahimi   // the start of the code buffer must be provided, as the literal only knows it
317*f5c631daSSadaf Ebrahimi   // offset from there. This also allows patching the value after the code has
318*f5c631daSSadaf Ebrahimi   // been moved in memory.
319*f5c631daSSadaf Ebrahimi   void UpdateValue(T new_value, uint8_t* code_buffer = NULL) {
320*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(sizeof(new_value) == size_);
321*f5c631daSSadaf Ebrahimi     memcpy(&low64_, &new_value, sizeof(new_value));
322*f5c631daSSadaf Ebrahimi     if (IsPlaced()) {
323*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(code_buffer != NULL);
324*f5c631daSSadaf Ebrahimi       RewriteValueInCode(code_buffer);
325*f5c631daSSadaf Ebrahimi     }
326*f5c631daSSadaf Ebrahimi   }
327*f5c631daSSadaf Ebrahimi 
328*f5c631daSSadaf Ebrahimi   void UpdateValue(T high64, T low64, uint8_t* code_buffer = NULL) {
329*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(sizeof(low64) == size_ / 2);
330*f5c631daSSadaf Ebrahimi     memcpy(&low64_, &low64, sizeof(low64));
331*f5c631daSSadaf Ebrahimi     memcpy(&high64_, &high64, sizeof(high64));
332*f5c631daSSadaf Ebrahimi     if (IsPlaced()) {
333*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(code_buffer != NULL);
334*f5c631daSSadaf Ebrahimi       RewriteValueInCode(code_buffer);
335*f5c631daSSadaf Ebrahimi     }
336*f5c631daSSadaf Ebrahimi   }
337*f5c631daSSadaf Ebrahimi 
338*f5c631daSSadaf Ebrahimi   void UpdateValue(T new_value, const Assembler* assembler);
339*f5c631daSSadaf Ebrahimi   void UpdateValue(T high64, T low64, const Assembler* assembler);
340*f5c631daSSadaf Ebrahimi 
341*f5c631daSSadaf Ebrahimi  private:
RewriteValueInCode(uint8_t * code_buffer)342*f5c631daSSadaf Ebrahimi   void RewriteValueInCode(uint8_t* code_buffer) {
343*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsPlaced());
344*f5c631daSSadaf Ebrahimi     VIXL_STATIC_ASSERT(sizeof(T) <= kXRegSizeInBytes);
345*f5c631daSSadaf Ebrahimi     switch (GetSize()) {
346*f5c631daSSadaf Ebrahimi       case kSRegSizeInBytes:
347*f5c631daSSadaf Ebrahimi         *reinterpret_cast<uint32_t*>(code_buffer + GetOffset()) =
348*f5c631daSSadaf Ebrahimi             GetRawValue32();
349*f5c631daSSadaf Ebrahimi         break;
350*f5c631daSSadaf Ebrahimi       case kDRegSizeInBytes:
351*f5c631daSSadaf Ebrahimi         *reinterpret_cast<uint64_t*>(code_buffer + GetOffset()) =
352*f5c631daSSadaf Ebrahimi             GetRawValue64();
353*f5c631daSSadaf Ebrahimi         break;
354*f5c631daSSadaf Ebrahimi       default:
355*f5c631daSSadaf Ebrahimi         VIXL_ASSERT(GetSize() == kQRegSizeInBytes);
356*f5c631daSSadaf Ebrahimi         uint64_t* base_address =
357*f5c631daSSadaf Ebrahimi             reinterpret_cast<uint64_t*>(code_buffer + GetOffset());
358*f5c631daSSadaf Ebrahimi         *base_address = GetRawValue128Low64();
359*f5c631daSSadaf Ebrahimi         *(base_address + 1) = GetRawValue128High64();
360*f5c631daSSadaf Ebrahimi     }
361*f5c631daSSadaf Ebrahimi   }
362*f5c631daSSadaf Ebrahimi };
363*f5c631daSSadaf Ebrahimi 
364*f5c631daSSadaf Ebrahimi 
365*f5c631daSSadaf Ebrahimi // Control whether or not position-independent code should be emitted.
366*f5c631daSSadaf Ebrahimi enum PositionIndependentCodeOption {
367*f5c631daSSadaf Ebrahimi   // All code generated will be position-independent; all branches and
368*f5c631daSSadaf Ebrahimi   // references to labels generated with the Label class will use PC-relative
369*f5c631daSSadaf Ebrahimi   // addressing.
370*f5c631daSSadaf Ebrahimi   PositionIndependentCode,
371*f5c631daSSadaf Ebrahimi 
372*f5c631daSSadaf Ebrahimi   // Allow VIXL to generate code that refers to absolute addresses. With this
373*f5c631daSSadaf Ebrahimi   // option, it will not be possible to copy the code buffer and run it from a
374*f5c631daSSadaf Ebrahimi   // different address; code must be generated in its final location.
375*f5c631daSSadaf Ebrahimi   PositionDependentCode,
376*f5c631daSSadaf Ebrahimi 
377*f5c631daSSadaf Ebrahimi   // Allow VIXL to assume that the bottom 12 bits of the address will be
378*f5c631daSSadaf Ebrahimi   // constant, but that the top 48 bits may change. This allows `adrp` to
379*f5c631daSSadaf Ebrahimi   // function in systems which copy code between pages, but otherwise maintain
380*f5c631daSSadaf Ebrahimi   // 4KB page alignment.
381*f5c631daSSadaf Ebrahimi   PageOffsetDependentCode
382*f5c631daSSadaf Ebrahimi };
383*f5c631daSSadaf Ebrahimi 
384*f5c631daSSadaf Ebrahimi 
385*f5c631daSSadaf Ebrahimi // Control how scaled- and unscaled-offset loads and stores are generated.
386*f5c631daSSadaf Ebrahimi enum LoadStoreScalingOption {
387*f5c631daSSadaf Ebrahimi   // Prefer scaled-immediate-offset instructions, but emit unscaled-offset,
388*f5c631daSSadaf Ebrahimi   // register-offset, pre-index or post-index instructions if necessary.
389*f5c631daSSadaf Ebrahimi   PreferScaledOffset,
390*f5c631daSSadaf Ebrahimi 
391*f5c631daSSadaf Ebrahimi   // Prefer unscaled-immediate-offset instructions, but emit scaled-offset,
392*f5c631daSSadaf Ebrahimi   // register-offset, pre-index or post-index instructions if necessary.
393*f5c631daSSadaf Ebrahimi   PreferUnscaledOffset,
394*f5c631daSSadaf Ebrahimi 
395*f5c631daSSadaf Ebrahimi   // Require scaled-immediate-offset instructions.
396*f5c631daSSadaf Ebrahimi   RequireScaledOffset,
397*f5c631daSSadaf Ebrahimi 
398*f5c631daSSadaf Ebrahimi   // Require unscaled-immediate-offset instructions.
399*f5c631daSSadaf Ebrahimi   RequireUnscaledOffset
400*f5c631daSSadaf Ebrahimi };
401*f5c631daSSadaf Ebrahimi 
402*f5c631daSSadaf Ebrahimi 
403*f5c631daSSadaf Ebrahimi // Assembler.
404*f5c631daSSadaf Ebrahimi class Assembler : public vixl::internal::AssemblerBase {
405*f5c631daSSadaf Ebrahimi  public:
406*f5c631daSSadaf Ebrahimi   explicit Assembler(
407*f5c631daSSadaf Ebrahimi       PositionIndependentCodeOption pic = PositionIndependentCode)
pic_(pic)408*f5c631daSSadaf Ebrahimi       : pic_(pic), cpu_features_(CPUFeatures::AArch64LegacyBaseline()) {}
409*f5c631daSSadaf Ebrahimi   explicit Assembler(
410*f5c631daSSadaf Ebrahimi       size_t capacity,
411*f5c631daSSadaf Ebrahimi       PositionIndependentCodeOption pic = PositionIndependentCode)
AssemblerBase(capacity)412*f5c631daSSadaf Ebrahimi       : AssemblerBase(capacity),
413*f5c631daSSadaf Ebrahimi         pic_(pic),
414*f5c631daSSadaf Ebrahimi         cpu_features_(CPUFeatures::AArch64LegacyBaseline()) {}
415*f5c631daSSadaf Ebrahimi   Assembler(byte* buffer,
416*f5c631daSSadaf Ebrahimi             size_t capacity,
417*f5c631daSSadaf Ebrahimi             PositionIndependentCodeOption pic = PositionIndependentCode)
AssemblerBase(buffer,capacity)418*f5c631daSSadaf Ebrahimi       : AssemblerBase(buffer, capacity),
419*f5c631daSSadaf Ebrahimi         pic_(pic),
420*f5c631daSSadaf Ebrahimi         cpu_features_(CPUFeatures::AArch64LegacyBaseline()) {}
421*f5c631daSSadaf Ebrahimi 
422*f5c631daSSadaf Ebrahimi   // Upon destruction, the code will assert that one of the following is true:
423*f5c631daSSadaf Ebrahimi   //  * The Assembler object has not been used.
424*f5c631daSSadaf Ebrahimi   //  * Nothing has been emitted since the last Reset() call.
425*f5c631daSSadaf Ebrahimi   //  * Nothing has been emitted since the last FinalizeCode() call.
~Assembler()426*f5c631daSSadaf Ebrahimi   ~Assembler() {}
427*f5c631daSSadaf Ebrahimi 
428*f5c631daSSadaf Ebrahimi   // System functions.
429*f5c631daSSadaf Ebrahimi 
430*f5c631daSSadaf Ebrahimi   // Start generating code from the beginning of the buffer, discarding any code
431*f5c631daSSadaf Ebrahimi   // and data that has already been emitted into the buffer.
432*f5c631daSSadaf Ebrahimi   void Reset();
433*f5c631daSSadaf Ebrahimi 
434*f5c631daSSadaf Ebrahimi   // Bind a label to the current PC.
435*f5c631daSSadaf Ebrahimi   void bind(Label* label);
436*f5c631daSSadaf Ebrahimi 
437*f5c631daSSadaf Ebrahimi   // Bind a label to a specified offset from the start of the buffer.
438*f5c631daSSadaf Ebrahimi   void BindToOffset(Label* label, ptrdiff_t offset);
439*f5c631daSSadaf Ebrahimi 
440*f5c631daSSadaf Ebrahimi   // Place a literal at the current PC.
441*f5c631daSSadaf Ebrahimi   void place(RawLiteral* literal);
442*f5c631daSSadaf Ebrahimi 
443*f5c631daSSadaf Ebrahimi   VIXL_DEPRECATED("GetCursorOffset", ptrdiff_t CursorOffset() const) {
444*f5c631daSSadaf Ebrahimi     return GetCursorOffset();
445*f5c631daSSadaf Ebrahimi   }
446*f5c631daSSadaf Ebrahimi 
447*f5c631daSSadaf Ebrahimi   VIXL_DEPRECATED("GetBuffer().GetCapacity()",
448*f5c631daSSadaf Ebrahimi                   ptrdiff_t GetBufferEndOffset() const) {
449*f5c631daSSadaf Ebrahimi     return static_cast<ptrdiff_t>(GetBuffer().GetCapacity());
450*f5c631daSSadaf Ebrahimi   }
451*f5c631daSSadaf Ebrahimi   VIXL_DEPRECATED("GetBuffer().GetCapacity()",
452*f5c631daSSadaf Ebrahimi                   ptrdiff_t BufferEndOffset() const) {
453*f5c631daSSadaf Ebrahimi     return GetBuffer().GetCapacity();
454*f5c631daSSadaf Ebrahimi   }
455*f5c631daSSadaf Ebrahimi 
456*f5c631daSSadaf Ebrahimi   // Return the address of a bound label.
457*f5c631daSSadaf Ebrahimi   template <typename T>
GetLabelAddress(const Label * label)458*f5c631daSSadaf Ebrahimi   T GetLabelAddress(const Label* label) const {
459*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(label->IsBound());
460*f5c631daSSadaf Ebrahimi     VIXL_STATIC_ASSERT(sizeof(T) >= sizeof(uintptr_t));
461*f5c631daSSadaf Ebrahimi     return GetBuffer().GetOffsetAddress<T>(label->GetLocation());
462*f5c631daSSadaf Ebrahimi   }
463*f5c631daSSadaf Ebrahimi 
GetInstructionAt(ptrdiff_t instruction_offset)464*f5c631daSSadaf Ebrahimi   Instruction* GetInstructionAt(ptrdiff_t instruction_offset) {
465*f5c631daSSadaf Ebrahimi     return GetBuffer()->GetOffsetAddress<Instruction*>(instruction_offset);
466*f5c631daSSadaf Ebrahimi   }
467*f5c631daSSadaf Ebrahimi   VIXL_DEPRECATED("GetInstructionAt",
468*f5c631daSSadaf Ebrahimi                   Instruction* InstructionAt(ptrdiff_t instruction_offset)) {
469*f5c631daSSadaf Ebrahimi     return GetInstructionAt(instruction_offset);
470*f5c631daSSadaf Ebrahimi   }
471*f5c631daSSadaf Ebrahimi 
GetInstructionOffset(Instruction * instruction)472*f5c631daSSadaf Ebrahimi   ptrdiff_t GetInstructionOffset(Instruction* instruction) {
473*f5c631daSSadaf Ebrahimi     VIXL_STATIC_ASSERT(sizeof(*instruction) == 1);
474*f5c631daSSadaf Ebrahimi     ptrdiff_t offset =
475*f5c631daSSadaf Ebrahimi         instruction - GetBuffer()->GetStartAddress<Instruction*>();
476*f5c631daSSadaf Ebrahimi     VIXL_ASSERT((0 <= offset) &&
477*f5c631daSSadaf Ebrahimi                 (offset < static_cast<ptrdiff_t>(GetBuffer()->GetCapacity())));
478*f5c631daSSadaf Ebrahimi     return offset;
479*f5c631daSSadaf Ebrahimi   }
480*f5c631daSSadaf Ebrahimi   VIXL_DEPRECATED("GetInstructionOffset",
481*f5c631daSSadaf Ebrahimi                   ptrdiff_t InstructionOffset(Instruction* instruction)) {
482*f5c631daSSadaf Ebrahimi     return GetInstructionOffset(instruction);
483*f5c631daSSadaf Ebrahimi   }
484*f5c631daSSadaf Ebrahimi 
485*f5c631daSSadaf Ebrahimi   // Instruction set functions.
486*f5c631daSSadaf Ebrahimi 
487*f5c631daSSadaf Ebrahimi   // Branch / Jump instructions.
488*f5c631daSSadaf Ebrahimi 
489*f5c631daSSadaf Ebrahimi   // Branch to register.
490*f5c631daSSadaf Ebrahimi   void br(const Register& xn);
491*f5c631daSSadaf Ebrahimi 
492*f5c631daSSadaf Ebrahimi   // Branch with link to register.
493*f5c631daSSadaf Ebrahimi   void blr(const Register& xn);
494*f5c631daSSadaf Ebrahimi 
495*f5c631daSSadaf Ebrahimi   // Branch to register with return hint.
496*f5c631daSSadaf Ebrahimi   void ret(const Register& xn = lr);
497*f5c631daSSadaf Ebrahimi 
498*f5c631daSSadaf Ebrahimi   // Branch to register, with pointer authentication. Using key A and a modifier
499*f5c631daSSadaf Ebrahimi   // of zero [Armv8.3].
500*f5c631daSSadaf Ebrahimi   void braaz(const Register& xn);
501*f5c631daSSadaf Ebrahimi 
502*f5c631daSSadaf Ebrahimi   // Branch to register, with pointer authentication. Using key B and a modifier
503*f5c631daSSadaf Ebrahimi   // of zero [Armv8.3].
504*f5c631daSSadaf Ebrahimi   void brabz(const Register& xn);
505*f5c631daSSadaf Ebrahimi 
506*f5c631daSSadaf Ebrahimi   // Branch with link to register, with pointer authentication. Using key A and
507*f5c631daSSadaf Ebrahimi   // a modifier of zero [Armv8.3].
508*f5c631daSSadaf Ebrahimi   void blraaz(const Register& xn);
509*f5c631daSSadaf Ebrahimi 
510*f5c631daSSadaf Ebrahimi   // Branch with link to register, with pointer authentication. Using key B and
511*f5c631daSSadaf Ebrahimi   // a modifier of zero [Armv8.3].
512*f5c631daSSadaf Ebrahimi   void blrabz(const Register& xn);
513*f5c631daSSadaf Ebrahimi 
514*f5c631daSSadaf Ebrahimi   // Return from subroutine, with pointer authentication. Using key A [Armv8.3].
515*f5c631daSSadaf Ebrahimi   void retaa();
516*f5c631daSSadaf Ebrahimi 
517*f5c631daSSadaf Ebrahimi   // Return from subroutine, with pointer authentication. Using key B [Armv8.3].
518*f5c631daSSadaf Ebrahimi   void retab();
519*f5c631daSSadaf Ebrahimi 
520*f5c631daSSadaf Ebrahimi   // Branch to register, with pointer authentication. Using key A [Armv8.3].
521*f5c631daSSadaf Ebrahimi   void braa(const Register& xn, const Register& xm);
522*f5c631daSSadaf Ebrahimi 
523*f5c631daSSadaf Ebrahimi   // Branch to register, with pointer authentication. Using key B [Armv8.3].
524*f5c631daSSadaf Ebrahimi   void brab(const Register& xn, const Register& xm);
525*f5c631daSSadaf Ebrahimi 
526*f5c631daSSadaf Ebrahimi   // Branch with link to register, with pointer authentication. Using key A
527*f5c631daSSadaf Ebrahimi   // [Armv8.3].
528*f5c631daSSadaf Ebrahimi   void blraa(const Register& xn, const Register& xm);
529*f5c631daSSadaf Ebrahimi 
530*f5c631daSSadaf Ebrahimi   // Branch with link to register, with pointer authentication. Using key B
531*f5c631daSSadaf Ebrahimi   // [Armv8.3].
532*f5c631daSSadaf Ebrahimi   void blrab(const Register& xn, const Register& xm);
533*f5c631daSSadaf Ebrahimi 
534*f5c631daSSadaf Ebrahimi   // Unconditional branch to label.
535*f5c631daSSadaf Ebrahimi   void b(Label* label);
536*f5c631daSSadaf Ebrahimi 
537*f5c631daSSadaf Ebrahimi   // Conditional branch to label.
538*f5c631daSSadaf Ebrahimi   void b(Label* label, Condition cond);
539*f5c631daSSadaf Ebrahimi 
540*f5c631daSSadaf Ebrahimi   // Unconditional branch to PC offset.
541*f5c631daSSadaf Ebrahimi   void b(int64_t imm26);
542*f5c631daSSadaf Ebrahimi 
543*f5c631daSSadaf Ebrahimi   // Conditional branch to PC offset.
544*f5c631daSSadaf Ebrahimi   void b(int64_t imm19, Condition cond);
545*f5c631daSSadaf Ebrahimi 
546*f5c631daSSadaf Ebrahimi   // Branch with link to label.
547*f5c631daSSadaf Ebrahimi   void bl(Label* label);
548*f5c631daSSadaf Ebrahimi 
549*f5c631daSSadaf Ebrahimi   // Branch with link to PC offset.
550*f5c631daSSadaf Ebrahimi   void bl(int64_t imm26);
551*f5c631daSSadaf Ebrahimi 
552*f5c631daSSadaf Ebrahimi   // Compare and branch to label if zero.
553*f5c631daSSadaf Ebrahimi   void cbz(const Register& rt, Label* label);
554*f5c631daSSadaf Ebrahimi 
555*f5c631daSSadaf Ebrahimi   // Compare and branch to PC offset if zero.
556*f5c631daSSadaf Ebrahimi   void cbz(const Register& rt, int64_t imm19);
557*f5c631daSSadaf Ebrahimi 
558*f5c631daSSadaf Ebrahimi   // Compare and branch to label if not zero.
559*f5c631daSSadaf Ebrahimi   void cbnz(const Register& rt, Label* label);
560*f5c631daSSadaf Ebrahimi 
561*f5c631daSSadaf Ebrahimi   // Compare and branch to PC offset if not zero.
562*f5c631daSSadaf Ebrahimi   void cbnz(const Register& rt, int64_t imm19);
563*f5c631daSSadaf Ebrahimi 
564*f5c631daSSadaf Ebrahimi   // Table lookup from one register.
565*f5c631daSSadaf Ebrahimi   void tbl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
566*f5c631daSSadaf Ebrahimi 
567*f5c631daSSadaf Ebrahimi   // Table lookup from two registers.
568*f5c631daSSadaf Ebrahimi   void tbl(const VRegister& vd,
569*f5c631daSSadaf Ebrahimi            const VRegister& vn,
570*f5c631daSSadaf Ebrahimi            const VRegister& vn2,
571*f5c631daSSadaf Ebrahimi            const VRegister& vm);
572*f5c631daSSadaf Ebrahimi 
573*f5c631daSSadaf Ebrahimi   // Table lookup from three registers.
574*f5c631daSSadaf Ebrahimi   void tbl(const VRegister& vd,
575*f5c631daSSadaf Ebrahimi            const VRegister& vn,
576*f5c631daSSadaf Ebrahimi            const VRegister& vn2,
577*f5c631daSSadaf Ebrahimi            const VRegister& vn3,
578*f5c631daSSadaf Ebrahimi            const VRegister& vm);
579*f5c631daSSadaf Ebrahimi 
580*f5c631daSSadaf Ebrahimi   // Table lookup from four registers.
581*f5c631daSSadaf Ebrahimi   void tbl(const VRegister& vd,
582*f5c631daSSadaf Ebrahimi            const VRegister& vn,
583*f5c631daSSadaf Ebrahimi            const VRegister& vn2,
584*f5c631daSSadaf Ebrahimi            const VRegister& vn3,
585*f5c631daSSadaf Ebrahimi            const VRegister& vn4,
586*f5c631daSSadaf Ebrahimi            const VRegister& vm);
587*f5c631daSSadaf Ebrahimi 
588*f5c631daSSadaf Ebrahimi   // Table lookup extension from one register.
589*f5c631daSSadaf Ebrahimi   void tbx(const VRegister& vd, const VRegister& vn, const VRegister& vm);
590*f5c631daSSadaf Ebrahimi 
591*f5c631daSSadaf Ebrahimi   // Table lookup extension from two registers.
592*f5c631daSSadaf Ebrahimi   void tbx(const VRegister& vd,
593*f5c631daSSadaf Ebrahimi            const VRegister& vn,
594*f5c631daSSadaf Ebrahimi            const VRegister& vn2,
595*f5c631daSSadaf Ebrahimi            const VRegister& vm);
596*f5c631daSSadaf Ebrahimi 
597*f5c631daSSadaf Ebrahimi   // Table lookup extension from three registers.
598*f5c631daSSadaf Ebrahimi   void tbx(const VRegister& vd,
599*f5c631daSSadaf Ebrahimi            const VRegister& vn,
600*f5c631daSSadaf Ebrahimi            const VRegister& vn2,
601*f5c631daSSadaf Ebrahimi            const VRegister& vn3,
602*f5c631daSSadaf Ebrahimi            const VRegister& vm);
603*f5c631daSSadaf Ebrahimi 
604*f5c631daSSadaf Ebrahimi   // Table lookup extension from four registers.
605*f5c631daSSadaf Ebrahimi   void tbx(const VRegister& vd,
606*f5c631daSSadaf Ebrahimi            const VRegister& vn,
607*f5c631daSSadaf Ebrahimi            const VRegister& vn2,
608*f5c631daSSadaf Ebrahimi            const VRegister& vn3,
609*f5c631daSSadaf Ebrahimi            const VRegister& vn4,
610*f5c631daSSadaf Ebrahimi            const VRegister& vm);
611*f5c631daSSadaf Ebrahimi 
612*f5c631daSSadaf Ebrahimi   // Test bit and branch to label if zero.
613*f5c631daSSadaf Ebrahimi   void tbz(const Register& rt, unsigned bit_pos, Label* label);
614*f5c631daSSadaf Ebrahimi 
615*f5c631daSSadaf Ebrahimi   // Test bit and branch to PC offset if zero.
616*f5c631daSSadaf Ebrahimi   void tbz(const Register& rt, unsigned bit_pos, int64_t imm14);
617*f5c631daSSadaf Ebrahimi 
618*f5c631daSSadaf Ebrahimi   // Test bit and branch to label if not zero.
619*f5c631daSSadaf Ebrahimi   void tbnz(const Register& rt, unsigned bit_pos, Label* label);
620*f5c631daSSadaf Ebrahimi 
621*f5c631daSSadaf Ebrahimi   // Test bit and branch to PC offset if not zero.
622*f5c631daSSadaf Ebrahimi   void tbnz(const Register& rt, unsigned bit_pos, int64_t imm14);
623*f5c631daSSadaf Ebrahimi 
624*f5c631daSSadaf Ebrahimi   // Address calculation instructions.
625*f5c631daSSadaf Ebrahimi   // Calculate a PC-relative address. Unlike for branches the offset in adr is
626*f5c631daSSadaf Ebrahimi   // unscaled (i.e. the result can be unaligned).
627*f5c631daSSadaf Ebrahimi 
628*f5c631daSSadaf Ebrahimi   // Calculate the address of a label.
629*f5c631daSSadaf Ebrahimi   void adr(const Register& xd, Label* label);
630*f5c631daSSadaf Ebrahimi 
631*f5c631daSSadaf Ebrahimi   // Calculate the address of a PC offset.
632*f5c631daSSadaf Ebrahimi   void adr(const Register& xd, int64_t imm21);
633*f5c631daSSadaf Ebrahimi 
634*f5c631daSSadaf Ebrahimi   // Calculate the page address of a label.
635*f5c631daSSadaf Ebrahimi   void adrp(const Register& xd, Label* label);
636*f5c631daSSadaf Ebrahimi 
637*f5c631daSSadaf Ebrahimi   // Calculate the page address of a PC offset.
638*f5c631daSSadaf Ebrahimi   void adrp(const Register& xd, int64_t imm21);
639*f5c631daSSadaf Ebrahimi 
640*f5c631daSSadaf Ebrahimi   // Data Processing instructions.
641*f5c631daSSadaf Ebrahimi 
642*f5c631daSSadaf Ebrahimi   // Add.
643*f5c631daSSadaf Ebrahimi   void add(const Register& rd, const Register& rn, const Operand& operand);
644*f5c631daSSadaf Ebrahimi 
645*f5c631daSSadaf Ebrahimi   // Add and update status flags.
646*f5c631daSSadaf Ebrahimi   void adds(const Register& rd, const Register& rn, const Operand& operand);
647*f5c631daSSadaf Ebrahimi 
648*f5c631daSSadaf Ebrahimi   // Compare negative.
649*f5c631daSSadaf Ebrahimi   void cmn(const Register& rn, const Operand& operand);
650*f5c631daSSadaf Ebrahimi 
651*f5c631daSSadaf Ebrahimi   // Subtract.
652*f5c631daSSadaf Ebrahimi   void sub(const Register& rd, const Register& rn, const Operand& operand);
653*f5c631daSSadaf Ebrahimi 
654*f5c631daSSadaf Ebrahimi   // Subtract and update status flags.
655*f5c631daSSadaf Ebrahimi   void subs(const Register& rd, const Register& rn, const Operand& operand);
656*f5c631daSSadaf Ebrahimi 
657*f5c631daSSadaf Ebrahimi   // Compare.
658*f5c631daSSadaf Ebrahimi   void cmp(const Register& rn, const Operand& operand);
659*f5c631daSSadaf Ebrahimi 
660*f5c631daSSadaf Ebrahimi   // Negate.
661*f5c631daSSadaf Ebrahimi   void neg(const Register& rd, const Operand& operand);
662*f5c631daSSadaf Ebrahimi 
663*f5c631daSSadaf Ebrahimi   // Negate and update status flags.
664*f5c631daSSadaf Ebrahimi   void negs(const Register& rd, const Operand& operand);
665*f5c631daSSadaf Ebrahimi 
666*f5c631daSSadaf Ebrahimi   // Add with carry bit.
667*f5c631daSSadaf Ebrahimi   void adc(const Register& rd, const Register& rn, const Operand& operand);
668*f5c631daSSadaf Ebrahimi 
669*f5c631daSSadaf Ebrahimi   // Add with carry bit and update status flags.
670*f5c631daSSadaf Ebrahimi   void adcs(const Register& rd, const Register& rn, const Operand& operand);
671*f5c631daSSadaf Ebrahimi 
672*f5c631daSSadaf Ebrahimi   // Subtract with carry bit.
673*f5c631daSSadaf Ebrahimi   void sbc(const Register& rd, const Register& rn, const Operand& operand);
674*f5c631daSSadaf Ebrahimi 
675*f5c631daSSadaf Ebrahimi   // Subtract with carry bit and update status flags.
676*f5c631daSSadaf Ebrahimi   void sbcs(const Register& rd, const Register& rn, const Operand& operand);
677*f5c631daSSadaf Ebrahimi 
678*f5c631daSSadaf Ebrahimi   // Rotate register right and insert into NZCV flags under the control of a
679*f5c631daSSadaf Ebrahimi   // mask [Armv8.4].
680*f5c631daSSadaf Ebrahimi   void rmif(const Register& xn, unsigned rotation, StatusFlags flags);
681*f5c631daSSadaf Ebrahimi 
682*f5c631daSSadaf Ebrahimi   // Set NZCV flags from register, treated as an 8-bit value [Armv8.4].
683*f5c631daSSadaf Ebrahimi   void setf8(const Register& rn);
684*f5c631daSSadaf Ebrahimi 
685*f5c631daSSadaf Ebrahimi   // Set NZCV flags from register, treated as an 16-bit value [Armv8.4].
686*f5c631daSSadaf Ebrahimi   void setf16(const Register& rn);
687*f5c631daSSadaf Ebrahimi 
688*f5c631daSSadaf Ebrahimi   // Negate with carry bit.
689*f5c631daSSadaf Ebrahimi   void ngc(const Register& rd, const Operand& operand);
690*f5c631daSSadaf Ebrahimi 
691*f5c631daSSadaf Ebrahimi   // Negate with carry bit and update status flags.
692*f5c631daSSadaf Ebrahimi   void ngcs(const Register& rd, const Operand& operand);
693*f5c631daSSadaf Ebrahimi 
694*f5c631daSSadaf Ebrahimi   // Logical instructions.
695*f5c631daSSadaf Ebrahimi 
696*f5c631daSSadaf Ebrahimi   // Bitwise and (A & B).
697*f5c631daSSadaf Ebrahimi   void and_(const Register& rd, const Register& rn, const Operand& operand);
698*f5c631daSSadaf Ebrahimi 
699*f5c631daSSadaf Ebrahimi   // Bitwise and (A & B) and update status flags.
700*f5c631daSSadaf Ebrahimi   void ands(const Register& rd, const Register& rn, const Operand& operand);
701*f5c631daSSadaf Ebrahimi 
702*f5c631daSSadaf Ebrahimi   // Bit test and set flags.
703*f5c631daSSadaf Ebrahimi   void tst(const Register& rn, const Operand& operand);
704*f5c631daSSadaf Ebrahimi 
705*f5c631daSSadaf Ebrahimi   // Bit clear (A & ~B).
706*f5c631daSSadaf Ebrahimi   void bic(const Register& rd, const Register& rn, const Operand& operand);
707*f5c631daSSadaf Ebrahimi 
708*f5c631daSSadaf Ebrahimi   // Bit clear (A & ~B) and update status flags.
709*f5c631daSSadaf Ebrahimi   void bics(const Register& rd, const Register& rn, const Operand& operand);
710*f5c631daSSadaf Ebrahimi 
711*f5c631daSSadaf Ebrahimi   // Bitwise or (A | B).
712*f5c631daSSadaf Ebrahimi   void orr(const Register& rd, const Register& rn, const Operand& operand);
713*f5c631daSSadaf Ebrahimi 
714*f5c631daSSadaf Ebrahimi   // Bitwise nor (A | ~B).
715*f5c631daSSadaf Ebrahimi   void orn(const Register& rd, const Register& rn, const Operand& operand);
716*f5c631daSSadaf Ebrahimi 
717*f5c631daSSadaf Ebrahimi   // Bitwise eor/xor (A ^ B).
718*f5c631daSSadaf Ebrahimi   void eor(const Register& rd, const Register& rn, const Operand& operand);
719*f5c631daSSadaf Ebrahimi 
720*f5c631daSSadaf Ebrahimi   // Bitwise enor/xnor (A ^ ~B).
721*f5c631daSSadaf Ebrahimi   void eon(const Register& rd, const Register& rn, const Operand& operand);
722*f5c631daSSadaf Ebrahimi 
723*f5c631daSSadaf Ebrahimi   // Logical shift left by variable.
724*f5c631daSSadaf Ebrahimi   void lslv(const Register& rd, const Register& rn, const Register& rm);
725*f5c631daSSadaf Ebrahimi 
726*f5c631daSSadaf Ebrahimi   // Logical shift right by variable.
727*f5c631daSSadaf Ebrahimi   void lsrv(const Register& rd, const Register& rn, const Register& rm);
728*f5c631daSSadaf Ebrahimi 
729*f5c631daSSadaf Ebrahimi   // Arithmetic shift right by variable.
730*f5c631daSSadaf Ebrahimi   void asrv(const Register& rd, const Register& rn, const Register& rm);
731*f5c631daSSadaf Ebrahimi 
732*f5c631daSSadaf Ebrahimi   // Rotate right by variable.
733*f5c631daSSadaf Ebrahimi   void rorv(const Register& rd, const Register& rn, const Register& rm);
734*f5c631daSSadaf Ebrahimi 
735*f5c631daSSadaf Ebrahimi   // Bitfield instructions.
736*f5c631daSSadaf Ebrahimi 
737*f5c631daSSadaf Ebrahimi   // Bitfield move.
738*f5c631daSSadaf Ebrahimi   void bfm(const Register& rd,
739*f5c631daSSadaf Ebrahimi            const Register& rn,
740*f5c631daSSadaf Ebrahimi            unsigned immr,
741*f5c631daSSadaf Ebrahimi            unsigned imms);
742*f5c631daSSadaf Ebrahimi 
743*f5c631daSSadaf Ebrahimi   // Signed bitfield move.
744*f5c631daSSadaf Ebrahimi   void sbfm(const Register& rd,
745*f5c631daSSadaf Ebrahimi             const Register& rn,
746*f5c631daSSadaf Ebrahimi             unsigned immr,
747*f5c631daSSadaf Ebrahimi             unsigned imms);
748*f5c631daSSadaf Ebrahimi 
749*f5c631daSSadaf Ebrahimi   // Unsigned bitfield move.
750*f5c631daSSadaf Ebrahimi   void ubfm(const Register& rd,
751*f5c631daSSadaf Ebrahimi             const Register& rn,
752*f5c631daSSadaf Ebrahimi             unsigned immr,
753*f5c631daSSadaf Ebrahimi             unsigned imms);
754*f5c631daSSadaf Ebrahimi 
755*f5c631daSSadaf Ebrahimi   // Bfm aliases.
756*f5c631daSSadaf Ebrahimi 
757*f5c631daSSadaf Ebrahimi   // Bitfield insert.
bfi(const Register & rd,const Register & rn,unsigned lsb,unsigned width)758*f5c631daSSadaf Ebrahimi   void bfi(const Register& rd,
759*f5c631daSSadaf Ebrahimi            const Register& rn,
760*f5c631daSSadaf Ebrahimi            unsigned lsb,
761*f5c631daSSadaf Ebrahimi            unsigned width) {
762*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(width >= 1);
763*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(lsb + width <= static_cast<unsigned>(rn.GetSizeInBits()));
764*f5c631daSSadaf Ebrahimi     bfm(rd,
765*f5c631daSSadaf Ebrahimi         rn,
766*f5c631daSSadaf Ebrahimi         (rd.GetSizeInBits() - lsb) & (rd.GetSizeInBits() - 1),
767*f5c631daSSadaf Ebrahimi         width - 1);
768*f5c631daSSadaf Ebrahimi   }
769*f5c631daSSadaf Ebrahimi 
770*f5c631daSSadaf Ebrahimi   // Bitfield extract and insert low.
bfxil(const Register & rd,const Register & rn,unsigned lsb,unsigned width)771*f5c631daSSadaf Ebrahimi   void bfxil(const Register& rd,
772*f5c631daSSadaf Ebrahimi              const Register& rn,
773*f5c631daSSadaf Ebrahimi              unsigned lsb,
774*f5c631daSSadaf Ebrahimi              unsigned width) {
775*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(width >= 1);
776*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(lsb + width <= static_cast<unsigned>(rn.GetSizeInBits()));
777*f5c631daSSadaf Ebrahimi     bfm(rd, rn, lsb, lsb + width - 1);
778*f5c631daSSadaf Ebrahimi   }
779*f5c631daSSadaf Ebrahimi 
780*f5c631daSSadaf Ebrahimi   // Bitfield clear [Armv8.2].
bfc(const Register & rd,unsigned lsb,unsigned width)781*f5c631daSSadaf Ebrahimi   void bfc(const Register& rd, unsigned lsb, unsigned width) {
782*f5c631daSSadaf Ebrahimi     bfi(rd, AppropriateZeroRegFor(rd), lsb, width);
783*f5c631daSSadaf Ebrahimi   }
784*f5c631daSSadaf Ebrahimi 
785*f5c631daSSadaf Ebrahimi   // Sbfm aliases.
786*f5c631daSSadaf Ebrahimi 
787*f5c631daSSadaf Ebrahimi   // Arithmetic shift right.
asr(const Register & rd,const Register & rn,unsigned shift)788*f5c631daSSadaf Ebrahimi   void asr(const Register& rd, const Register& rn, unsigned shift) {
789*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(shift < static_cast<unsigned>(rd.GetSizeInBits()));
790*f5c631daSSadaf Ebrahimi     sbfm(rd, rn, shift, rd.GetSizeInBits() - 1);
791*f5c631daSSadaf Ebrahimi   }
792*f5c631daSSadaf Ebrahimi 
793*f5c631daSSadaf Ebrahimi   // Signed bitfield insert with zero at right.
sbfiz(const Register & rd,const Register & rn,unsigned lsb,unsigned width)794*f5c631daSSadaf Ebrahimi   void sbfiz(const Register& rd,
795*f5c631daSSadaf Ebrahimi              const Register& rn,
796*f5c631daSSadaf Ebrahimi              unsigned lsb,
797*f5c631daSSadaf Ebrahimi              unsigned width) {
798*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(width >= 1);
799*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(lsb + width <= static_cast<unsigned>(rn.GetSizeInBits()));
800*f5c631daSSadaf Ebrahimi     sbfm(rd,
801*f5c631daSSadaf Ebrahimi          rn,
802*f5c631daSSadaf Ebrahimi          (rd.GetSizeInBits() - lsb) & (rd.GetSizeInBits() - 1),
803*f5c631daSSadaf Ebrahimi          width - 1);
804*f5c631daSSadaf Ebrahimi   }
805*f5c631daSSadaf Ebrahimi 
806*f5c631daSSadaf Ebrahimi   // Signed bitfield extract.
sbfx(const Register & rd,const Register & rn,unsigned lsb,unsigned width)807*f5c631daSSadaf Ebrahimi   void sbfx(const Register& rd,
808*f5c631daSSadaf Ebrahimi             const Register& rn,
809*f5c631daSSadaf Ebrahimi             unsigned lsb,
810*f5c631daSSadaf Ebrahimi             unsigned width) {
811*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(width >= 1);
812*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(lsb + width <= static_cast<unsigned>(rn.GetSizeInBits()));
813*f5c631daSSadaf Ebrahimi     sbfm(rd, rn, lsb, lsb + width - 1);
814*f5c631daSSadaf Ebrahimi   }
815*f5c631daSSadaf Ebrahimi 
816*f5c631daSSadaf Ebrahimi   // Signed extend byte.
sxtb(const Register & rd,const Register & rn)817*f5c631daSSadaf Ebrahimi   void sxtb(const Register& rd, const Register& rn) { sbfm(rd, rn, 0, 7); }
818*f5c631daSSadaf Ebrahimi 
819*f5c631daSSadaf Ebrahimi   // Signed extend halfword.
sxth(const Register & rd,const Register & rn)820*f5c631daSSadaf Ebrahimi   void sxth(const Register& rd, const Register& rn) { sbfm(rd, rn, 0, 15); }
821*f5c631daSSadaf Ebrahimi 
822*f5c631daSSadaf Ebrahimi   // Signed extend word.
sxtw(const Register & rd,const Register & rn)823*f5c631daSSadaf Ebrahimi   void sxtw(const Register& rd, const Register& rn) { sbfm(rd, rn, 0, 31); }
824*f5c631daSSadaf Ebrahimi 
825*f5c631daSSadaf Ebrahimi   // Ubfm aliases.
826*f5c631daSSadaf Ebrahimi 
827*f5c631daSSadaf Ebrahimi   // Logical shift left.
lsl(const Register & rd,const Register & rn,unsigned shift)828*f5c631daSSadaf Ebrahimi   void lsl(const Register& rd, const Register& rn, unsigned shift) {
829*f5c631daSSadaf Ebrahimi     unsigned reg_size = rd.GetSizeInBits();
830*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(shift < reg_size);
831*f5c631daSSadaf Ebrahimi     ubfm(rd, rn, (reg_size - shift) % reg_size, reg_size - shift - 1);
832*f5c631daSSadaf Ebrahimi   }
833*f5c631daSSadaf Ebrahimi 
834*f5c631daSSadaf Ebrahimi   // Logical shift right.
lsr(const Register & rd,const Register & rn,unsigned shift)835*f5c631daSSadaf Ebrahimi   void lsr(const Register& rd, const Register& rn, unsigned shift) {
836*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(shift < static_cast<unsigned>(rd.GetSizeInBits()));
837*f5c631daSSadaf Ebrahimi     ubfm(rd, rn, shift, rd.GetSizeInBits() - 1);
838*f5c631daSSadaf Ebrahimi   }
839*f5c631daSSadaf Ebrahimi 
840*f5c631daSSadaf Ebrahimi   // Unsigned bitfield insert with zero at right.
ubfiz(const Register & rd,const Register & rn,unsigned lsb,unsigned width)841*f5c631daSSadaf Ebrahimi   void ubfiz(const Register& rd,
842*f5c631daSSadaf Ebrahimi              const Register& rn,
843*f5c631daSSadaf Ebrahimi              unsigned lsb,
844*f5c631daSSadaf Ebrahimi              unsigned width) {
845*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(width >= 1);
846*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(lsb + width <= static_cast<unsigned>(rn.GetSizeInBits()));
847*f5c631daSSadaf Ebrahimi     ubfm(rd,
848*f5c631daSSadaf Ebrahimi          rn,
849*f5c631daSSadaf Ebrahimi          (rd.GetSizeInBits() - lsb) & (rd.GetSizeInBits() - 1),
850*f5c631daSSadaf Ebrahimi          width - 1);
851*f5c631daSSadaf Ebrahimi   }
852*f5c631daSSadaf Ebrahimi 
853*f5c631daSSadaf Ebrahimi   // Unsigned bitfield extract.
ubfx(const Register & rd,const Register & rn,unsigned lsb,unsigned width)854*f5c631daSSadaf Ebrahimi   void ubfx(const Register& rd,
855*f5c631daSSadaf Ebrahimi             const Register& rn,
856*f5c631daSSadaf Ebrahimi             unsigned lsb,
857*f5c631daSSadaf Ebrahimi             unsigned width) {
858*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(width >= 1);
859*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(lsb + width <= static_cast<unsigned>(rn.GetSizeInBits()));
860*f5c631daSSadaf Ebrahimi     ubfm(rd, rn, lsb, lsb + width - 1);
861*f5c631daSSadaf Ebrahimi   }
862*f5c631daSSadaf Ebrahimi 
863*f5c631daSSadaf Ebrahimi   // Unsigned extend byte.
uxtb(const Register & rd,const Register & rn)864*f5c631daSSadaf Ebrahimi   void uxtb(const Register& rd, const Register& rn) { ubfm(rd, rn, 0, 7); }
865*f5c631daSSadaf Ebrahimi 
866*f5c631daSSadaf Ebrahimi   // Unsigned extend halfword.
uxth(const Register & rd,const Register & rn)867*f5c631daSSadaf Ebrahimi   void uxth(const Register& rd, const Register& rn) { ubfm(rd, rn, 0, 15); }
868*f5c631daSSadaf Ebrahimi 
869*f5c631daSSadaf Ebrahimi   // Unsigned extend word.
uxtw(const Register & rd,const Register & rn)870*f5c631daSSadaf Ebrahimi   void uxtw(const Register& rd, const Register& rn) { ubfm(rd, rn, 0, 31); }
871*f5c631daSSadaf Ebrahimi 
872*f5c631daSSadaf Ebrahimi   // Extract.
873*f5c631daSSadaf Ebrahimi   void extr(const Register& rd,
874*f5c631daSSadaf Ebrahimi             const Register& rn,
875*f5c631daSSadaf Ebrahimi             const Register& rm,
876*f5c631daSSadaf Ebrahimi             unsigned lsb);
877*f5c631daSSadaf Ebrahimi 
878*f5c631daSSadaf Ebrahimi   // Conditional select: rd = cond ? rn : rm.
879*f5c631daSSadaf Ebrahimi   void csel(const Register& rd,
880*f5c631daSSadaf Ebrahimi             const Register& rn,
881*f5c631daSSadaf Ebrahimi             const Register& rm,
882*f5c631daSSadaf Ebrahimi             Condition cond);
883*f5c631daSSadaf Ebrahimi 
884*f5c631daSSadaf Ebrahimi   // Conditional select increment: rd = cond ? rn : rm + 1.
885*f5c631daSSadaf Ebrahimi   void csinc(const Register& rd,
886*f5c631daSSadaf Ebrahimi              const Register& rn,
887*f5c631daSSadaf Ebrahimi              const Register& rm,
888*f5c631daSSadaf Ebrahimi              Condition cond);
889*f5c631daSSadaf Ebrahimi 
890*f5c631daSSadaf Ebrahimi   // Conditional select inversion: rd = cond ? rn : ~rm.
891*f5c631daSSadaf Ebrahimi   void csinv(const Register& rd,
892*f5c631daSSadaf Ebrahimi              const Register& rn,
893*f5c631daSSadaf Ebrahimi              const Register& rm,
894*f5c631daSSadaf Ebrahimi              Condition cond);
895*f5c631daSSadaf Ebrahimi 
896*f5c631daSSadaf Ebrahimi   // Conditional select negation: rd = cond ? rn : -rm.
897*f5c631daSSadaf Ebrahimi   void csneg(const Register& rd,
898*f5c631daSSadaf Ebrahimi              const Register& rn,
899*f5c631daSSadaf Ebrahimi              const Register& rm,
900*f5c631daSSadaf Ebrahimi              Condition cond);
901*f5c631daSSadaf Ebrahimi 
902*f5c631daSSadaf Ebrahimi   // Conditional set: rd = cond ? 1 : 0.
903*f5c631daSSadaf Ebrahimi   void cset(const Register& rd, Condition cond);
904*f5c631daSSadaf Ebrahimi 
905*f5c631daSSadaf Ebrahimi   // Conditional set mask: rd = cond ? -1 : 0.
906*f5c631daSSadaf Ebrahimi   void csetm(const Register& rd, Condition cond);
907*f5c631daSSadaf Ebrahimi 
908*f5c631daSSadaf Ebrahimi   // Conditional increment: rd = cond ? rn + 1 : rn.
909*f5c631daSSadaf Ebrahimi   void cinc(const Register& rd, const Register& rn, Condition cond);
910*f5c631daSSadaf Ebrahimi 
911*f5c631daSSadaf Ebrahimi   // Conditional invert: rd = cond ? ~rn : rn.
912*f5c631daSSadaf Ebrahimi   void cinv(const Register& rd, const Register& rn, Condition cond);
913*f5c631daSSadaf Ebrahimi 
914*f5c631daSSadaf Ebrahimi   // Conditional negate: rd = cond ? -rn : rn.
915*f5c631daSSadaf Ebrahimi   void cneg(const Register& rd, const Register& rn, Condition cond);
916*f5c631daSSadaf Ebrahimi 
917*f5c631daSSadaf Ebrahimi   // Rotate right.
ror(const Register & rd,const Register & rs,unsigned shift)918*f5c631daSSadaf Ebrahimi   void ror(const Register& rd, const Register& rs, unsigned shift) {
919*f5c631daSSadaf Ebrahimi     extr(rd, rs, rs, shift);
920*f5c631daSSadaf Ebrahimi   }
921*f5c631daSSadaf Ebrahimi 
922*f5c631daSSadaf Ebrahimi   // Conditional comparison.
923*f5c631daSSadaf Ebrahimi 
924*f5c631daSSadaf Ebrahimi   // Conditional compare negative.
925*f5c631daSSadaf Ebrahimi   void ccmn(const Register& rn,
926*f5c631daSSadaf Ebrahimi             const Operand& operand,
927*f5c631daSSadaf Ebrahimi             StatusFlags nzcv,
928*f5c631daSSadaf Ebrahimi             Condition cond);
929*f5c631daSSadaf Ebrahimi 
930*f5c631daSSadaf Ebrahimi   // Conditional compare.
931*f5c631daSSadaf Ebrahimi   void ccmp(const Register& rn,
932*f5c631daSSadaf Ebrahimi             const Operand& operand,
933*f5c631daSSadaf Ebrahimi             StatusFlags nzcv,
934*f5c631daSSadaf Ebrahimi             Condition cond);
935*f5c631daSSadaf Ebrahimi 
936*f5c631daSSadaf Ebrahimi   // CRC-32 checksum from byte.
937*f5c631daSSadaf Ebrahimi   void crc32b(const Register& wd, const Register& wn, const Register& wm);
938*f5c631daSSadaf Ebrahimi 
939*f5c631daSSadaf Ebrahimi   // CRC-32 checksum from half-word.
940*f5c631daSSadaf Ebrahimi   void crc32h(const Register& wd, const Register& wn, const Register& wm);
941*f5c631daSSadaf Ebrahimi 
942*f5c631daSSadaf Ebrahimi   // CRC-32 checksum from word.
943*f5c631daSSadaf Ebrahimi   void crc32w(const Register& wd, const Register& wn, const Register& wm);
944*f5c631daSSadaf Ebrahimi 
945*f5c631daSSadaf Ebrahimi   // CRC-32 checksum from double word.
946*f5c631daSSadaf Ebrahimi   void crc32x(const Register& wd, const Register& wn, const Register& xm);
947*f5c631daSSadaf Ebrahimi 
948*f5c631daSSadaf Ebrahimi   // CRC-32 C checksum from byte.
949*f5c631daSSadaf Ebrahimi   void crc32cb(const Register& wd, const Register& wn, const Register& wm);
950*f5c631daSSadaf Ebrahimi 
951*f5c631daSSadaf Ebrahimi   // CRC-32 C checksum from half-word.
952*f5c631daSSadaf Ebrahimi   void crc32ch(const Register& wd, const Register& wn, const Register& wm);
953*f5c631daSSadaf Ebrahimi 
954*f5c631daSSadaf Ebrahimi   // CRC-32 C checksum from word.
955*f5c631daSSadaf Ebrahimi   void crc32cw(const Register& wd, const Register& wn, const Register& wm);
956*f5c631daSSadaf Ebrahimi 
957*f5c631daSSadaf Ebrahimi   // CRC-32C checksum from double word.
958*f5c631daSSadaf Ebrahimi   void crc32cx(const Register& wd, const Register& wn, const Register& xm);
959*f5c631daSSadaf Ebrahimi 
960*f5c631daSSadaf Ebrahimi   // Multiply.
961*f5c631daSSadaf Ebrahimi   void mul(const Register& rd, const Register& rn, const Register& rm);
962*f5c631daSSadaf Ebrahimi 
963*f5c631daSSadaf Ebrahimi   // Negated multiply.
964*f5c631daSSadaf Ebrahimi   void mneg(const Register& rd, const Register& rn, const Register& rm);
965*f5c631daSSadaf Ebrahimi 
966*f5c631daSSadaf Ebrahimi   // Signed long multiply: 32 x 32 -> 64-bit.
967*f5c631daSSadaf Ebrahimi   void smull(const Register& xd, const Register& wn, const Register& wm);
968*f5c631daSSadaf Ebrahimi 
969*f5c631daSSadaf Ebrahimi   // Signed multiply high: 64 x 64 -> 64-bit <127:64>.
970*f5c631daSSadaf Ebrahimi   void smulh(const Register& xd, const Register& xn, const Register& xm);
971*f5c631daSSadaf Ebrahimi 
972*f5c631daSSadaf Ebrahimi   // Multiply and accumulate.
973*f5c631daSSadaf Ebrahimi   void madd(const Register& rd,
974*f5c631daSSadaf Ebrahimi             const Register& rn,
975*f5c631daSSadaf Ebrahimi             const Register& rm,
976*f5c631daSSadaf Ebrahimi             const Register& ra);
977*f5c631daSSadaf Ebrahimi 
978*f5c631daSSadaf Ebrahimi   // Multiply and subtract.
979*f5c631daSSadaf Ebrahimi   void msub(const Register& rd,
980*f5c631daSSadaf Ebrahimi             const Register& rn,
981*f5c631daSSadaf Ebrahimi             const Register& rm,
982*f5c631daSSadaf Ebrahimi             const Register& ra);
983*f5c631daSSadaf Ebrahimi 
984*f5c631daSSadaf Ebrahimi   // Signed long multiply and accumulate: 32 x 32 + 64 -> 64-bit.
985*f5c631daSSadaf Ebrahimi   void smaddl(const Register& xd,
986*f5c631daSSadaf Ebrahimi               const Register& wn,
987*f5c631daSSadaf Ebrahimi               const Register& wm,
988*f5c631daSSadaf Ebrahimi               const Register& xa);
989*f5c631daSSadaf Ebrahimi 
990*f5c631daSSadaf Ebrahimi   // Unsigned long multiply and accumulate: 32 x 32 + 64 -> 64-bit.
991*f5c631daSSadaf Ebrahimi   void umaddl(const Register& xd,
992*f5c631daSSadaf Ebrahimi               const Register& wn,
993*f5c631daSSadaf Ebrahimi               const Register& wm,
994*f5c631daSSadaf Ebrahimi               const Register& xa);
995*f5c631daSSadaf Ebrahimi 
996*f5c631daSSadaf Ebrahimi   // Unsigned long multiply: 32 x 32 -> 64-bit.
umull(const Register & xd,const Register & wn,const Register & wm)997*f5c631daSSadaf Ebrahimi   void umull(const Register& xd, const Register& wn, const Register& wm) {
998*f5c631daSSadaf Ebrahimi     umaddl(xd, wn, wm, xzr);
999*f5c631daSSadaf Ebrahimi   }
1000*f5c631daSSadaf Ebrahimi 
1001*f5c631daSSadaf Ebrahimi   // Unsigned multiply high: 64 x 64 -> 64-bit <127:64>.
1002*f5c631daSSadaf Ebrahimi   void umulh(const Register& xd, const Register& xn, const Register& xm);
1003*f5c631daSSadaf Ebrahimi 
1004*f5c631daSSadaf Ebrahimi   // Signed long multiply and subtract: 64 - (32 x 32) -> 64-bit.
1005*f5c631daSSadaf Ebrahimi   void smsubl(const Register& xd,
1006*f5c631daSSadaf Ebrahimi               const Register& wn,
1007*f5c631daSSadaf Ebrahimi               const Register& wm,
1008*f5c631daSSadaf Ebrahimi               const Register& xa);
1009*f5c631daSSadaf Ebrahimi 
1010*f5c631daSSadaf Ebrahimi   // Unsigned long multiply and subtract: 64 - (32 x 32) -> 64-bit.
1011*f5c631daSSadaf Ebrahimi   void umsubl(const Register& xd,
1012*f5c631daSSadaf Ebrahimi               const Register& wn,
1013*f5c631daSSadaf Ebrahimi               const Register& wm,
1014*f5c631daSSadaf Ebrahimi               const Register& xa);
1015*f5c631daSSadaf Ebrahimi 
1016*f5c631daSSadaf Ebrahimi   // Signed integer divide.
1017*f5c631daSSadaf Ebrahimi   void sdiv(const Register& rd, const Register& rn, const Register& rm);
1018*f5c631daSSadaf Ebrahimi 
1019*f5c631daSSadaf Ebrahimi   // Unsigned integer divide.
1020*f5c631daSSadaf Ebrahimi   void udiv(const Register& rd, const Register& rn, const Register& rm);
1021*f5c631daSSadaf Ebrahimi 
1022*f5c631daSSadaf Ebrahimi   // Bit reverse.
1023*f5c631daSSadaf Ebrahimi   void rbit(const Register& rd, const Register& rn);
1024*f5c631daSSadaf Ebrahimi 
1025*f5c631daSSadaf Ebrahimi   // Reverse bytes in 16-bit half words.
1026*f5c631daSSadaf Ebrahimi   void rev16(const Register& rd, const Register& rn);
1027*f5c631daSSadaf Ebrahimi 
1028*f5c631daSSadaf Ebrahimi   // Reverse bytes in 32-bit words.
1029*f5c631daSSadaf Ebrahimi   void rev32(const Register& xd, const Register& xn);
1030*f5c631daSSadaf Ebrahimi 
1031*f5c631daSSadaf Ebrahimi   // Reverse bytes in 64-bit general purpose register, an alias for rev
1032*f5c631daSSadaf Ebrahimi   // [Armv8.2].
rev64(const Register & xd,const Register & xn)1033*f5c631daSSadaf Ebrahimi   void rev64(const Register& xd, const Register& xn) {
1034*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(xd.Is64Bits() && xn.Is64Bits());
1035*f5c631daSSadaf Ebrahimi     rev(xd, xn);
1036*f5c631daSSadaf Ebrahimi   }
1037*f5c631daSSadaf Ebrahimi 
1038*f5c631daSSadaf Ebrahimi   // Reverse bytes.
1039*f5c631daSSadaf Ebrahimi   void rev(const Register& rd, const Register& rn);
1040*f5c631daSSadaf Ebrahimi 
1041*f5c631daSSadaf Ebrahimi   // Count leading zeroes.
1042*f5c631daSSadaf Ebrahimi   void clz(const Register& rd, const Register& rn);
1043*f5c631daSSadaf Ebrahimi 
1044*f5c631daSSadaf Ebrahimi   // Count leading sign bits.
1045*f5c631daSSadaf Ebrahimi   void cls(const Register& rd, const Register& rn);
1046*f5c631daSSadaf Ebrahimi 
1047*f5c631daSSadaf Ebrahimi   // Pointer Authentication Code for Instruction address, using key A [Armv8.3].
1048*f5c631daSSadaf Ebrahimi   void pacia(const Register& xd, const Register& rn);
1049*f5c631daSSadaf Ebrahimi 
1050*f5c631daSSadaf Ebrahimi   // Pointer Authentication Code for Instruction address, using key A and a
1051*f5c631daSSadaf Ebrahimi   // modifier of zero [Armv8.3].
1052*f5c631daSSadaf Ebrahimi   void paciza(const Register& xd);
1053*f5c631daSSadaf Ebrahimi 
1054*f5c631daSSadaf Ebrahimi   // Pointer Authentication Code for Instruction address, using key A, with
1055*f5c631daSSadaf Ebrahimi   // address in x17 and modifier in x16 [Armv8.3].
1056*f5c631daSSadaf Ebrahimi   void pacia1716();
1057*f5c631daSSadaf Ebrahimi 
1058*f5c631daSSadaf Ebrahimi   // Pointer Authentication Code for Instruction address, using key A, with
1059*f5c631daSSadaf Ebrahimi   // address in LR and modifier in SP [Armv8.3].
1060*f5c631daSSadaf Ebrahimi   void paciasp();
1061*f5c631daSSadaf Ebrahimi 
1062*f5c631daSSadaf Ebrahimi   // Pointer Authentication Code for Instruction address, using key A, with
1063*f5c631daSSadaf Ebrahimi   // address in LR and a modifier of zero [Armv8.3].
1064*f5c631daSSadaf Ebrahimi   void paciaz();
1065*f5c631daSSadaf Ebrahimi 
1066*f5c631daSSadaf Ebrahimi   // Pointer Authentication Code for Instruction address, using key B [Armv8.3].
1067*f5c631daSSadaf Ebrahimi   void pacib(const Register& xd, const Register& xn);
1068*f5c631daSSadaf Ebrahimi 
1069*f5c631daSSadaf Ebrahimi   // Pointer Authentication Code for Instruction address, using key B and a
1070*f5c631daSSadaf Ebrahimi   // modifier of zero [Armv8.3].
1071*f5c631daSSadaf Ebrahimi   void pacizb(const Register& xd);
1072*f5c631daSSadaf Ebrahimi 
1073*f5c631daSSadaf Ebrahimi   // Pointer Authentication Code for Instruction address, using key B, with
1074*f5c631daSSadaf Ebrahimi   // address in x17 and modifier in x16 [Armv8.3].
1075*f5c631daSSadaf Ebrahimi   void pacib1716();
1076*f5c631daSSadaf Ebrahimi 
1077*f5c631daSSadaf Ebrahimi   // Pointer Authentication Code for Instruction address, using key B, with
1078*f5c631daSSadaf Ebrahimi   // address in LR and modifier in SP [Armv8.3].
1079*f5c631daSSadaf Ebrahimi   void pacibsp();
1080*f5c631daSSadaf Ebrahimi 
1081*f5c631daSSadaf Ebrahimi   // Pointer Authentication Code for Instruction address, using key B, with
1082*f5c631daSSadaf Ebrahimi   // address in LR and a modifier of zero [Armv8.3].
1083*f5c631daSSadaf Ebrahimi   void pacibz();
1084*f5c631daSSadaf Ebrahimi 
1085*f5c631daSSadaf Ebrahimi   // Pointer Authentication Code for Data address, using key A [Armv8.3].
1086*f5c631daSSadaf Ebrahimi   void pacda(const Register& xd, const Register& xn);
1087*f5c631daSSadaf Ebrahimi 
1088*f5c631daSSadaf Ebrahimi   // Pointer Authentication Code for Data address, using key A and a modifier of
1089*f5c631daSSadaf Ebrahimi   // zero [Armv8.3].
1090*f5c631daSSadaf Ebrahimi   void pacdza(const Register& xd);
1091*f5c631daSSadaf Ebrahimi 
1092*f5c631daSSadaf Ebrahimi   // Pointer Authentication Code for Data address, using key B [Armv8.3].
1093*f5c631daSSadaf Ebrahimi   void pacdb(const Register& xd, const Register& xn);
1094*f5c631daSSadaf Ebrahimi 
1095*f5c631daSSadaf Ebrahimi   // Pointer Authentication Code for Data address, using key B and a modifier of
1096*f5c631daSSadaf Ebrahimi   // zero [Armv8.3].
1097*f5c631daSSadaf Ebrahimi   void pacdzb(const Register& xd);
1098*f5c631daSSadaf Ebrahimi 
1099*f5c631daSSadaf Ebrahimi   // Pointer Authentication Code, using Generic key [Armv8.3].
1100*f5c631daSSadaf Ebrahimi   void pacga(const Register& xd, const Register& xn, const Register& xm);
1101*f5c631daSSadaf Ebrahimi 
1102*f5c631daSSadaf Ebrahimi   // Authenticate Instruction address, using key A [Armv8.3].
1103*f5c631daSSadaf Ebrahimi   void autia(const Register& xd, const Register& xn);
1104*f5c631daSSadaf Ebrahimi 
1105*f5c631daSSadaf Ebrahimi   // Authenticate Instruction address, using key A and a modifier of zero
1106*f5c631daSSadaf Ebrahimi   // [Armv8.3].
1107*f5c631daSSadaf Ebrahimi   void autiza(const Register& xd);
1108*f5c631daSSadaf Ebrahimi 
1109*f5c631daSSadaf Ebrahimi   // Authenticate Instruction address, using key A, with address in x17 and
1110*f5c631daSSadaf Ebrahimi   // modifier in x16 [Armv8.3].
1111*f5c631daSSadaf Ebrahimi   void autia1716();
1112*f5c631daSSadaf Ebrahimi 
1113*f5c631daSSadaf Ebrahimi   // Authenticate Instruction address, using key A, with address in LR and
1114*f5c631daSSadaf Ebrahimi   // modifier in SP [Armv8.3].
1115*f5c631daSSadaf Ebrahimi   void autiasp();
1116*f5c631daSSadaf Ebrahimi 
1117*f5c631daSSadaf Ebrahimi   // Authenticate Instruction address, using key A, with address in LR and a
1118*f5c631daSSadaf Ebrahimi   // modifier of zero [Armv8.3].
1119*f5c631daSSadaf Ebrahimi   void autiaz();
1120*f5c631daSSadaf Ebrahimi 
1121*f5c631daSSadaf Ebrahimi   // Authenticate Instruction address, using key B [Armv8.3].
1122*f5c631daSSadaf Ebrahimi   void autib(const Register& xd, const Register& xn);
1123*f5c631daSSadaf Ebrahimi 
1124*f5c631daSSadaf Ebrahimi   // Authenticate Instruction address, using key B and a modifier of zero
1125*f5c631daSSadaf Ebrahimi   // [Armv8.3].
1126*f5c631daSSadaf Ebrahimi   void autizb(const Register& xd);
1127*f5c631daSSadaf Ebrahimi 
1128*f5c631daSSadaf Ebrahimi   // Authenticate Instruction address, using key B, with address in x17 and
1129*f5c631daSSadaf Ebrahimi   // modifier in x16 [Armv8.3].
1130*f5c631daSSadaf Ebrahimi   void autib1716();
1131*f5c631daSSadaf Ebrahimi 
1132*f5c631daSSadaf Ebrahimi   // Authenticate Instruction address, using key B, with address in LR and
1133*f5c631daSSadaf Ebrahimi   // modifier in SP [Armv8.3].
1134*f5c631daSSadaf Ebrahimi   void autibsp();
1135*f5c631daSSadaf Ebrahimi 
1136*f5c631daSSadaf Ebrahimi   // Authenticate Instruction address, using key B, with address in LR and a
1137*f5c631daSSadaf Ebrahimi   // modifier of zero [Armv8.3].
1138*f5c631daSSadaf Ebrahimi   void autibz();
1139*f5c631daSSadaf Ebrahimi 
1140*f5c631daSSadaf Ebrahimi   // Authenticate Data address, using key A [Armv8.3].
1141*f5c631daSSadaf Ebrahimi   void autda(const Register& xd, const Register& xn);
1142*f5c631daSSadaf Ebrahimi 
1143*f5c631daSSadaf Ebrahimi   // Authenticate Data address, using key A and a modifier of zero [Armv8.3].
1144*f5c631daSSadaf Ebrahimi   void autdza(const Register& xd);
1145*f5c631daSSadaf Ebrahimi 
1146*f5c631daSSadaf Ebrahimi   // Authenticate Data address, using key B [Armv8.3].
1147*f5c631daSSadaf Ebrahimi   void autdb(const Register& xd, const Register& xn);
1148*f5c631daSSadaf Ebrahimi 
1149*f5c631daSSadaf Ebrahimi   // Authenticate Data address, using key B and a modifier of zero [Armv8.3].
1150*f5c631daSSadaf Ebrahimi   void autdzb(const Register& xd);
1151*f5c631daSSadaf Ebrahimi 
1152*f5c631daSSadaf Ebrahimi   // Strip Pointer Authentication Code of Data address [Armv8.3].
1153*f5c631daSSadaf Ebrahimi   void xpacd(const Register& xd);
1154*f5c631daSSadaf Ebrahimi 
1155*f5c631daSSadaf Ebrahimi   // Strip Pointer Authentication Code of Instruction address [Armv8.3].
1156*f5c631daSSadaf Ebrahimi   void xpaci(const Register& xd);
1157*f5c631daSSadaf Ebrahimi 
1158*f5c631daSSadaf Ebrahimi   // Strip Pointer Authentication Code of Instruction address in LR [Armv8.3].
1159*f5c631daSSadaf Ebrahimi   void xpaclri();
1160*f5c631daSSadaf Ebrahimi 
1161*f5c631daSSadaf Ebrahimi   // Memory instructions.
1162*f5c631daSSadaf Ebrahimi 
1163*f5c631daSSadaf Ebrahimi   // Load integer or FP register.
1164*f5c631daSSadaf Ebrahimi   void ldr(const CPURegister& rt,
1165*f5c631daSSadaf Ebrahimi            const MemOperand& src,
1166*f5c631daSSadaf Ebrahimi            LoadStoreScalingOption option = PreferScaledOffset);
1167*f5c631daSSadaf Ebrahimi 
1168*f5c631daSSadaf Ebrahimi   // Store integer or FP register.
1169*f5c631daSSadaf Ebrahimi   void str(const CPURegister& rt,
1170*f5c631daSSadaf Ebrahimi            const MemOperand& dst,
1171*f5c631daSSadaf Ebrahimi            LoadStoreScalingOption option = PreferScaledOffset);
1172*f5c631daSSadaf Ebrahimi 
1173*f5c631daSSadaf Ebrahimi   // Load word with sign extension.
1174*f5c631daSSadaf Ebrahimi   void ldrsw(const Register& xt,
1175*f5c631daSSadaf Ebrahimi              const MemOperand& src,
1176*f5c631daSSadaf Ebrahimi              LoadStoreScalingOption option = PreferScaledOffset);
1177*f5c631daSSadaf Ebrahimi 
1178*f5c631daSSadaf Ebrahimi   // Load byte.
1179*f5c631daSSadaf Ebrahimi   void ldrb(const Register& rt,
1180*f5c631daSSadaf Ebrahimi             const MemOperand& src,
1181*f5c631daSSadaf Ebrahimi             LoadStoreScalingOption option = PreferScaledOffset);
1182*f5c631daSSadaf Ebrahimi 
1183*f5c631daSSadaf Ebrahimi   // Store byte.
1184*f5c631daSSadaf Ebrahimi   void strb(const Register& rt,
1185*f5c631daSSadaf Ebrahimi             const MemOperand& dst,
1186*f5c631daSSadaf Ebrahimi             LoadStoreScalingOption option = PreferScaledOffset);
1187*f5c631daSSadaf Ebrahimi 
1188*f5c631daSSadaf Ebrahimi   // Load byte with sign extension.
1189*f5c631daSSadaf Ebrahimi   void ldrsb(const Register& rt,
1190*f5c631daSSadaf Ebrahimi              const MemOperand& src,
1191*f5c631daSSadaf Ebrahimi              LoadStoreScalingOption option = PreferScaledOffset);
1192*f5c631daSSadaf Ebrahimi 
1193*f5c631daSSadaf Ebrahimi   // Load half-word.
1194*f5c631daSSadaf Ebrahimi   void ldrh(const Register& rt,
1195*f5c631daSSadaf Ebrahimi             const MemOperand& src,
1196*f5c631daSSadaf Ebrahimi             LoadStoreScalingOption option = PreferScaledOffset);
1197*f5c631daSSadaf Ebrahimi 
1198*f5c631daSSadaf Ebrahimi   // Store half-word.
1199*f5c631daSSadaf Ebrahimi   void strh(const Register& rt,
1200*f5c631daSSadaf Ebrahimi             const MemOperand& dst,
1201*f5c631daSSadaf Ebrahimi             LoadStoreScalingOption option = PreferScaledOffset);
1202*f5c631daSSadaf Ebrahimi 
1203*f5c631daSSadaf Ebrahimi   // Load half-word with sign extension.
1204*f5c631daSSadaf Ebrahimi   void ldrsh(const Register& rt,
1205*f5c631daSSadaf Ebrahimi              const MemOperand& src,
1206*f5c631daSSadaf Ebrahimi              LoadStoreScalingOption option = PreferScaledOffset);
1207*f5c631daSSadaf Ebrahimi 
1208*f5c631daSSadaf Ebrahimi   // Load integer or FP register (with unscaled offset).
1209*f5c631daSSadaf Ebrahimi   void ldur(const CPURegister& rt,
1210*f5c631daSSadaf Ebrahimi             const MemOperand& src,
1211*f5c631daSSadaf Ebrahimi             LoadStoreScalingOption option = PreferUnscaledOffset);
1212*f5c631daSSadaf Ebrahimi 
1213*f5c631daSSadaf Ebrahimi   // Store integer or FP register (with unscaled offset).
1214*f5c631daSSadaf Ebrahimi   void stur(const CPURegister& rt,
1215*f5c631daSSadaf Ebrahimi             const MemOperand& src,
1216*f5c631daSSadaf Ebrahimi             LoadStoreScalingOption option = PreferUnscaledOffset);
1217*f5c631daSSadaf Ebrahimi 
1218*f5c631daSSadaf Ebrahimi   // Load word with sign extension.
1219*f5c631daSSadaf Ebrahimi   void ldursw(const Register& xt,
1220*f5c631daSSadaf Ebrahimi               const MemOperand& src,
1221*f5c631daSSadaf Ebrahimi               LoadStoreScalingOption option = PreferUnscaledOffset);
1222*f5c631daSSadaf Ebrahimi 
1223*f5c631daSSadaf Ebrahimi   // Load byte (with unscaled offset).
1224*f5c631daSSadaf Ebrahimi   void ldurb(const Register& rt,
1225*f5c631daSSadaf Ebrahimi              const MemOperand& src,
1226*f5c631daSSadaf Ebrahimi              LoadStoreScalingOption option = PreferUnscaledOffset);
1227*f5c631daSSadaf Ebrahimi 
1228*f5c631daSSadaf Ebrahimi   // Store byte (with unscaled offset).
1229*f5c631daSSadaf Ebrahimi   void sturb(const Register& rt,
1230*f5c631daSSadaf Ebrahimi              const MemOperand& dst,
1231*f5c631daSSadaf Ebrahimi              LoadStoreScalingOption option = PreferUnscaledOffset);
1232*f5c631daSSadaf Ebrahimi 
1233*f5c631daSSadaf Ebrahimi   // Load byte with sign extension (and unscaled offset).
1234*f5c631daSSadaf Ebrahimi   void ldursb(const Register& rt,
1235*f5c631daSSadaf Ebrahimi               const MemOperand& src,
1236*f5c631daSSadaf Ebrahimi               LoadStoreScalingOption option = PreferUnscaledOffset);
1237*f5c631daSSadaf Ebrahimi 
1238*f5c631daSSadaf Ebrahimi   // Load half-word (with unscaled offset).
1239*f5c631daSSadaf Ebrahimi   void ldurh(const Register& rt,
1240*f5c631daSSadaf Ebrahimi              const MemOperand& src,
1241*f5c631daSSadaf Ebrahimi              LoadStoreScalingOption option = PreferUnscaledOffset);
1242*f5c631daSSadaf Ebrahimi 
1243*f5c631daSSadaf Ebrahimi   // Store half-word (with unscaled offset).
1244*f5c631daSSadaf Ebrahimi   void sturh(const Register& rt,
1245*f5c631daSSadaf Ebrahimi              const MemOperand& dst,
1246*f5c631daSSadaf Ebrahimi              LoadStoreScalingOption option = PreferUnscaledOffset);
1247*f5c631daSSadaf Ebrahimi 
1248*f5c631daSSadaf Ebrahimi   // Load half-word with sign extension (and unscaled offset).
1249*f5c631daSSadaf Ebrahimi   void ldursh(const Register& rt,
1250*f5c631daSSadaf Ebrahimi               const MemOperand& src,
1251*f5c631daSSadaf Ebrahimi               LoadStoreScalingOption option = PreferUnscaledOffset);
1252*f5c631daSSadaf Ebrahimi 
1253*f5c631daSSadaf Ebrahimi   // Load double-word with pointer authentication, using data key A and a
1254*f5c631daSSadaf Ebrahimi   // modifier of zero [Armv8.3].
1255*f5c631daSSadaf Ebrahimi   void ldraa(const Register& xt, const MemOperand& src);
1256*f5c631daSSadaf Ebrahimi 
1257*f5c631daSSadaf Ebrahimi   // Load double-word with pointer authentication, using data key B and a
1258*f5c631daSSadaf Ebrahimi   // modifier of zero [Armv8.3].
1259*f5c631daSSadaf Ebrahimi   void ldrab(const Register& xt, const MemOperand& src);
1260*f5c631daSSadaf Ebrahimi 
1261*f5c631daSSadaf Ebrahimi   // Load integer or FP register pair.
1262*f5c631daSSadaf Ebrahimi   void ldp(const CPURegister& rt,
1263*f5c631daSSadaf Ebrahimi            const CPURegister& rt2,
1264*f5c631daSSadaf Ebrahimi            const MemOperand& src);
1265*f5c631daSSadaf Ebrahimi 
1266*f5c631daSSadaf Ebrahimi   // Store integer or FP register pair.
1267*f5c631daSSadaf Ebrahimi   void stp(const CPURegister& rt,
1268*f5c631daSSadaf Ebrahimi            const CPURegister& rt2,
1269*f5c631daSSadaf Ebrahimi            const MemOperand& dst);
1270*f5c631daSSadaf Ebrahimi 
1271*f5c631daSSadaf Ebrahimi   // Load word pair with sign extension.
1272*f5c631daSSadaf Ebrahimi   void ldpsw(const Register& xt, const Register& xt2, const MemOperand& src);
1273*f5c631daSSadaf Ebrahimi 
1274*f5c631daSSadaf Ebrahimi   // Load integer or FP register pair, non-temporal.
1275*f5c631daSSadaf Ebrahimi   void ldnp(const CPURegister& rt,
1276*f5c631daSSadaf Ebrahimi             const CPURegister& rt2,
1277*f5c631daSSadaf Ebrahimi             const MemOperand& src);
1278*f5c631daSSadaf Ebrahimi 
1279*f5c631daSSadaf Ebrahimi   // Store integer or FP register pair, non-temporal.
1280*f5c631daSSadaf Ebrahimi   void stnp(const CPURegister& rt,
1281*f5c631daSSadaf Ebrahimi             const CPURegister& rt2,
1282*f5c631daSSadaf Ebrahimi             const MemOperand& dst);
1283*f5c631daSSadaf Ebrahimi 
1284*f5c631daSSadaf Ebrahimi   // Load integer or FP register from literal pool.
1285*f5c631daSSadaf Ebrahimi   void ldr(const CPURegister& rt, RawLiteral* literal);
1286*f5c631daSSadaf Ebrahimi 
1287*f5c631daSSadaf Ebrahimi   // Load word with sign extension from literal pool.
1288*f5c631daSSadaf Ebrahimi   void ldrsw(const Register& xt, RawLiteral* literal);
1289*f5c631daSSadaf Ebrahimi 
1290*f5c631daSSadaf Ebrahimi   // Load integer or FP register from pc + imm19 << 2.
1291*f5c631daSSadaf Ebrahimi   void ldr(const CPURegister& rt, int64_t imm19);
1292*f5c631daSSadaf Ebrahimi 
1293*f5c631daSSadaf Ebrahimi   // Load word with sign extension from pc + imm19 << 2.
1294*f5c631daSSadaf Ebrahimi   void ldrsw(const Register& xt, int64_t imm19);
1295*f5c631daSSadaf Ebrahimi 
1296*f5c631daSSadaf Ebrahimi   // Store exclusive byte.
1297*f5c631daSSadaf Ebrahimi   void stxrb(const Register& rs, const Register& rt, const MemOperand& dst);
1298*f5c631daSSadaf Ebrahimi 
1299*f5c631daSSadaf Ebrahimi   // Store exclusive half-word.
1300*f5c631daSSadaf Ebrahimi   void stxrh(const Register& rs, const Register& rt, const MemOperand& dst);
1301*f5c631daSSadaf Ebrahimi 
1302*f5c631daSSadaf Ebrahimi   // Store exclusive register.
1303*f5c631daSSadaf Ebrahimi   void stxr(const Register& rs, const Register& rt, const MemOperand& dst);
1304*f5c631daSSadaf Ebrahimi 
1305*f5c631daSSadaf Ebrahimi   // Load exclusive byte.
1306*f5c631daSSadaf Ebrahimi   void ldxrb(const Register& rt, const MemOperand& src);
1307*f5c631daSSadaf Ebrahimi 
1308*f5c631daSSadaf Ebrahimi   // Load exclusive half-word.
1309*f5c631daSSadaf Ebrahimi   void ldxrh(const Register& rt, const MemOperand& src);
1310*f5c631daSSadaf Ebrahimi 
1311*f5c631daSSadaf Ebrahimi   // Load exclusive register.
1312*f5c631daSSadaf Ebrahimi   void ldxr(const Register& rt, const MemOperand& src);
1313*f5c631daSSadaf Ebrahimi 
1314*f5c631daSSadaf Ebrahimi   // Store exclusive register pair.
1315*f5c631daSSadaf Ebrahimi   void stxp(const Register& rs,
1316*f5c631daSSadaf Ebrahimi             const Register& rt,
1317*f5c631daSSadaf Ebrahimi             const Register& rt2,
1318*f5c631daSSadaf Ebrahimi             const MemOperand& dst);
1319*f5c631daSSadaf Ebrahimi 
1320*f5c631daSSadaf Ebrahimi   // Load exclusive register pair.
1321*f5c631daSSadaf Ebrahimi   void ldxp(const Register& rt, const Register& rt2, const MemOperand& src);
1322*f5c631daSSadaf Ebrahimi 
1323*f5c631daSSadaf Ebrahimi   // Store-release exclusive byte.
1324*f5c631daSSadaf Ebrahimi   void stlxrb(const Register& rs, const Register& rt, const MemOperand& dst);
1325*f5c631daSSadaf Ebrahimi 
1326*f5c631daSSadaf Ebrahimi   // Store-release exclusive half-word.
1327*f5c631daSSadaf Ebrahimi   void stlxrh(const Register& rs, const Register& rt, const MemOperand& dst);
1328*f5c631daSSadaf Ebrahimi 
1329*f5c631daSSadaf Ebrahimi   // Store-release exclusive register.
1330*f5c631daSSadaf Ebrahimi   void stlxr(const Register& rs, const Register& rt, const MemOperand& dst);
1331*f5c631daSSadaf Ebrahimi 
1332*f5c631daSSadaf Ebrahimi   // Load-acquire exclusive byte.
1333*f5c631daSSadaf Ebrahimi   void ldaxrb(const Register& rt, const MemOperand& src);
1334*f5c631daSSadaf Ebrahimi 
1335*f5c631daSSadaf Ebrahimi   // Load-acquire exclusive half-word.
1336*f5c631daSSadaf Ebrahimi   void ldaxrh(const Register& rt, const MemOperand& src);
1337*f5c631daSSadaf Ebrahimi 
1338*f5c631daSSadaf Ebrahimi   // Load-acquire exclusive register.
1339*f5c631daSSadaf Ebrahimi   void ldaxr(const Register& rt, const MemOperand& src);
1340*f5c631daSSadaf Ebrahimi 
1341*f5c631daSSadaf Ebrahimi   // Store-release exclusive register pair.
1342*f5c631daSSadaf Ebrahimi   void stlxp(const Register& rs,
1343*f5c631daSSadaf Ebrahimi              const Register& rt,
1344*f5c631daSSadaf Ebrahimi              const Register& rt2,
1345*f5c631daSSadaf Ebrahimi              const MemOperand& dst);
1346*f5c631daSSadaf Ebrahimi 
1347*f5c631daSSadaf Ebrahimi   // Load-acquire exclusive register pair.
1348*f5c631daSSadaf Ebrahimi   void ldaxp(const Register& rt, const Register& rt2, const MemOperand& src);
1349*f5c631daSSadaf Ebrahimi 
1350*f5c631daSSadaf Ebrahimi   // Store-release byte.
1351*f5c631daSSadaf Ebrahimi   void stlrb(const Register& rt, const MemOperand& dst);
1352*f5c631daSSadaf Ebrahimi 
1353*f5c631daSSadaf Ebrahimi   // Store-release half-word.
1354*f5c631daSSadaf Ebrahimi   void stlrh(const Register& rt, const MemOperand& dst);
1355*f5c631daSSadaf Ebrahimi 
1356*f5c631daSSadaf Ebrahimi   // Store-release register.
1357*f5c631daSSadaf Ebrahimi   void stlr(const Register& rt, const MemOperand& dst);
1358*f5c631daSSadaf Ebrahimi 
1359*f5c631daSSadaf Ebrahimi   // Load-acquire byte.
1360*f5c631daSSadaf Ebrahimi   void ldarb(const Register& rt, const MemOperand& src);
1361*f5c631daSSadaf Ebrahimi 
1362*f5c631daSSadaf Ebrahimi   // Load-acquire half-word.
1363*f5c631daSSadaf Ebrahimi   void ldarh(const Register& rt, const MemOperand& src);
1364*f5c631daSSadaf Ebrahimi 
1365*f5c631daSSadaf Ebrahimi   // Load-acquire register.
1366*f5c631daSSadaf Ebrahimi   void ldar(const Register& rt, const MemOperand& src);
1367*f5c631daSSadaf Ebrahimi 
1368*f5c631daSSadaf Ebrahimi   // Store LORelease byte [Armv8.1].
1369*f5c631daSSadaf Ebrahimi   void stllrb(const Register& rt, const MemOperand& dst);
1370*f5c631daSSadaf Ebrahimi 
1371*f5c631daSSadaf Ebrahimi   // Store LORelease half-word [Armv8.1].
1372*f5c631daSSadaf Ebrahimi   void stllrh(const Register& rt, const MemOperand& dst);
1373*f5c631daSSadaf Ebrahimi 
1374*f5c631daSSadaf Ebrahimi   // Store LORelease register [Armv8.1].
1375*f5c631daSSadaf Ebrahimi   void stllr(const Register& rt, const MemOperand& dst);
1376*f5c631daSSadaf Ebrahimi 
1377*f5c631daSSadaf Ebrahimi   // Load LORelease byte [Armv8.1].
1378*f5c631daSSadaf Ebrahimi   void ldlarb(const Register& rt, const MemOperand& src);
1379*f5c631daSSadaf Ebrahimi 
1380*f5c631daSSadaf Ebrahimi   // Load LORelease half-word [Armv8.1].
1381*f5c631daSSadaf Ebrahimi   void ldlarh(const Register& rt, const MemOperand& src);
1382*f5c631daSSadaf Ebrahimi 
1383*f5c631daSSadaf Ebrahimi   // Load LORelease register [Armv8.1].
1384*f5c631daSSadaf Ebrahimi   void ldlar(const Register& rt, const MemOperand& src);
1385*f5c631daSSadaf Ebrahimi 
1386*f5c631daSSadaf Ebrahimi   // Compare and Swap word or doubleword in memory [Armv8.1].
1387*f5c631daSSadaf Ebrahimi   void cas(const Register& rs, const Register& rt, const MemOperand& src);
1388*f5c631daSSadaf Ebrahimi 
1389*f5c631daSSadaf Ebrahimi   // Compare and Swap word or doubleword in memory [Armv8.1].
1390*f5c631daSSadaf Ebrahimi   void casa(const Register& rs, const Register& rt, const MemOperand& src);
1391*f5c631daSSadaf Ebrahimi 
1392*f5c631daSSadaf Ebrahimi   // Compare and Swap word or doubleword in memory [Armv8.1].
1393*f5c631daSSadaf Ebrahimi   void casl(const Register& rs, const Register& rt, const MemOperand& src);
1394*f5c631daSSadaf Ebrahimi 
1395*f5c631daSSadaf Ebrahimi   // Compare and Swap word or doubleword in memory [Armv8.1].
1396*f5c631daSSadaf Ebrahimi   void casal(const Register& rs, const Register& rt, const MemOperand& src);
1397*f5c631daSSadaf Ebrahimi 
1398*f5c631daSSadaf Ebrahimi   // Compare and Swap byte in memory [Armv8.1].
1399*f5c631daSSadaf Ebrahimi   void casb(const Register& rs, const Register& rt, const MemOperand& src);
1400*f5c631daSSadaf Ebrahimi 
1401*f5c631daSSadaf Ebrahimi   // Compare and Swap byte in memory [Armv8.1].
1402*f5c631daSSadaf Ebrahimi   void casab(const Register& rs, const Register& rt, const MemOperand& src);
1403*f5c631daSSadaf Ebrahimi 
1404*f5c631daSSadaf Ebrahimi   // Compare and Swap byte in memory [Armv8.1].
1405*f5c631daSSadaf Ebrahimi   void caslb(const Register& rs, const Register& rt, const MemOperand& src);
1406*f5c631daSSadaf Ebrahimi 
1407*f5c631daSSadaf Ebrahimi   // Compare and Swap byte in memory [Armv8.1].
1408*f5c631daSSadaf Ebrahimi   void casalb(const Register& rs, const Register& rt, const MemOperand& src);
1409*f5c631daSSadaf Ebrahimi 
1410*f5c631daSSadaf Ebrahimi   // Compare and Swap halfword in memory [Armv8.1].
1411*f5c631daSSadaf Ebrahimi   void cash(const Register& rs, const Register& rt, const MemOperand& src);
1412*f5c631daSSadaf Ebrahimi 
1413*f5c631daSSadaf Ebrahimi   // Compare and Swap halfword in memory [Armv8.1].
1414*f5c631daSSadaf Ebrahimi   void casah(const Register& rs, const Register& rt, const MemOperand& src);
1415*f5c631daSSadaf Ebrahimi 
1416*f5c631daSSadaf Ebrahimi   // Compare and Swap halfword in memory [Armv8.1].
1417*f5c631daSSadaf Ebrahimi   void caslh(const Register& rs, const Register& rt, const MemOperand& src);
1418*f5c631daSSadaf Ebrahimi 
1419*f5c631daSSadaf Ebrahimi   // Compare and Swap halfword in memory [Armv8.1].
1420*f5c631daSSadaf Ebrahimi   void casalh(const Register& rs, const Register& rt, const MemOperand& src);
1421*f5c631daSSadaf Ebrahimi 
1422*f5c631daSSadaf Ebrahimi   // Compare and Swap Pair of words or doublewords in memory [Armv8.1].
1423*f5c631daSSadaf Ebrahimi   void casp(const Register& rs,
1424*f5c631daSSadaf Ebrahimi             const Register& rs2,
1425*f5c631daSSadaf Ebrahimi             const Register& rt,
1426*f5c631daSSadaf Ebrahimi             const Register& rt2,
1427*f5c631daSSadaf Ebrahimi             const MemOperand& src);
1428*f5c631daSSadaf Ebrahimi 
1429*f5c631daSSadaf Ebrahimi   // Compare and Swap Pair of words or doublewords in memory [Armv8.1].
1430*f5c631daSSadaf Ebrahimi   void caspa(const Register& rs,
1431*f5c631daSSadaf Ebrahimi              const Register& rs2,
1432*f5c631daSSadaf Ebrahimi              const Register& rt,
1433*f5c631daSSadaf Ebrahimi              const Register& rt2,
1434*f5c631daSSadaf Ebrahimi              const MemOperand& src);
1435*f5c631daSSadaf Ebrahimi 
1436*f5c631daSSadaf Ebrahimi   // Compare and Swap Pair of words or doublewords in memory [Armv8.1].
1437*f5c631daSSadaf Ebrahimi   void caspl(const Register& rs,
1438*f5c631daSSadaf Ebrahimi              const Register& rs2,
1439*f5c631daSSadaf Ebrahimi              const Register& rt,
1440*f5c631daSSadaf Ebrahimi              const Register& rt2,
1441*f5c631daSSadaf Ebrahimi              const MemOperand& src);
1442*f5c631daSSadaf Ebrahimi 
1443*f5c631daSSadaf Ebrahimi   // Compare and Swap Pair of words or doublewords in memory [Armv8.1].
1444*f5c631daSSadaf Ebrahimi   void caspal(const Register& rs,
1445*f5c631daSSadaf Ebrahimi               const Register& rs2,
1446*f5c631daSSadaf Ebrahimi               const Register& rt,
1447*f5c631daSSadaf Ebrahimi               const Register& rt2,
1448*f5c631daSSadaf Ebrahimi               const MemOperand& src);
1449*f5c631daSSadaf Ebrahimi 
1450*f5c631daSSadaf Ebrahimi   // Store-release byte (with unscaled offset) [Armv8.4].
1451*f5c631daSSadaf Ebrahimi   void stlurb(const Register& rt, const MemOperand& dst);
1452*f5c631daSSadaf Ebrahimi 
1453*f5c631daSSadaf Ebrahimi   // Load-acquire RCpc Register byte (with unscaled offset) [Armv8.4].
1454*f5c631daSSadaf Ebrahimi   void ldapurb(const Register& rt, const MemOperand& src);
1455*f5c631daSSadaf Ebrahimi 
1456*f5c631daSSadaf Ebrahimi   // Load-acquire RCpc Register signed byte (with unscaled offset) [Armv8.4].
1457*f5c631daSSadaf Ebrahimi   void ldapursb(const Register& rt, const MemOperand& src);
1458*f5c631daSSadaf Ebrahimi 
1459*f5c631daSSadaf Ebrahimi   // Store-release half-word (with unscaled offset) [Armv8.4].
1460*f5c631daSSadaf Ebrahimi   void stlurh(const Register& rt, const MemOperand& dst);
1461*f5c631daSSadaf Ebrahimi 
1462*f5c631daSSadaf Ebrahimi   // Load-acquire RCpc Register half-word (with unscaled offset) [Armv8.4].
1463*f5c631daSSadaf Ebrahimi   void ldapurh(const Register& rt, const MemOperand& src);
1464*f5c631daSSadaf Ebrahimi 
1465*f5c631daSSadaf Ebrahimi   // Load-acquire RCpc Register signed half-word (with unscaled offset)
1466*f5c631daSSadaf Ebrahimi   // [Armv8.4].
1467*f5c631daSSadaf Ebrahimi   void ldapursh(const Register& rt, const MemOperand& src);
1468*f5c631daSSadaf Ebrahimi 
1469*f5c631daSSadaf Ebrahimi   // Store-release word or double-word (with unscaled offset) [Armv8.4].
1470*f5c631daSSadaf Ebrahimi   void stlur(const Register& rt, const MemOperand& dst);
1471*f5c631daSSadaf Ebrahimi 
1472*f5c631daSSadaf Ebrahimi   // Load-acquire RCpc Register word or double-word (with unscaled offset)
1473*f5c631daSSadaf Ebrahimi   // [Armv8.4].
1474*f5c631daSSadaf Ebrahimi   void ldapur(const Register& rt, const MemOperand& src);
1475*f5c631daSSadaf Ebrahimi 
1476*f5c631daSSadaf Ebrahimi   // Load-acquire RCpc Register signed word (with unscaled offset) [Armv8.4].
1477*f5c631daSSadaf Ebrahimi   void ldapursw(const Register& xt, const MemOperand& src);
1478*f5c631daSSadaf Ebrahimi 
1479*f5c631daSSadaf Ebrahimi   // Atomic add on byte in memory [Armv8.1]
1480*f5c631daSSadaf Ebrahimi   void ldaddb(const Register& rs, const Register& rt, const MemOperand& src);
1481*f5c631daSSadaf Ebrahimi 
1482*f5c631daSSadaf Ebrahimi   // Atomic add on byte in memory, with Load-acquire semantics [Armv8.1]
1483*f5c631daSSadaf Ebrahimi   void ldaddab(const Register& rs, const Register& rt, const MemOperand& src);
1484*f5c631daSSadaf Ebrahimi 
1485*f5c631daSSadaf Ebrahimi   // Atomic add on byte in memory, with Store-release semantics [Armv8.1]
1486*f5c631daSSadaf Ebrahimi   void ldaddlb(const Register& rs, const Register& rt, const MemOperand& src);
1487*f5c631daSSadaf Ebrahimi 
1488*f5c631daSSadaf Ebrahimi   // Atomic add on byte in memory, with Load-acquire and Store-release semantics
1489*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1490*f5c631daSSadaf Ebrahimi   void ldaddalb(const Register& rs, const Register& rt, const MemOperand& src);
1491*f5c631daSSadaf Ebrahimi 
1492*f5c631daSSadaf Ebrahimi   // Atomic add on halfword in memory [Armv8.1]
1493*f5c631daSSadaf Ebrahimi   void ldaddh(const Register& rs, const Register& rt, const MemOperand& src);
1494*f5c631daSSadaf Ebrahimi 
1495*f5c631daSSadaf Ebrahimi   // Atomic add on halfword in memory, with Load-acquire semantics [Armv8.1]
1496*f5c631daSSadaf Ebrahimi   void ldaddah(const Register& rs, const Register& rt, const MemOperand& src);
1497*f5c631daSSadaf Ebrahimi 
1498*f5c631daSSadaf Ebrahimi   // Atomic add on halfword in memory, with Store-release semantics [Armv8.1]
1499*f5c631daSSadaf Ebrahimi   void ldaddlh(const Register& rs, const Register& rt, const MemOperand& src);
1500*f5c631daSSadaf Ebrahimi 
1501*f5c631daSSadaf Ebrahimi   // Atomic add on halfword in memory, with Load-acquire and Store-release
1502*f5c631daSSadaf Ebrahimi   // semantics [Armv8.1]
1503*f5c631daSSadaf Ebrahimi   void ldaddalh(const Register& rs, const Register& rt, const MemOperand& src);
1504*f5c631daSSadaf Ebrahimi 
1505*f5c631daSSadaf Ebrahimi   // Atomic add on word or doubleword in memory [Armv8.1]
1506*f5c631daSSadaf Ebrahimi   void ldadd(const Register& rs, const Register& rt, const MemOperand& src);
1507*f5c631daSSadaf Ebrahimi 
1508*f5c631daSSadaf Ebrahimi   // Atomic add on word or doubleword in memory, with Load-acquire semantics
1509*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1510*f5c631daSSadaf Ebrahimi   void ldadda(const Register& rs, const Register& rt, const MemOperand& src);
1511*f5c631daSSadaf Ebrahimi 
1512*f5c631daSSadaf Ebrahimi   // Atomic add on word or doubleword in memory, with Store-release semantics
1513*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1514*f5c631daSSadaf Ebrahimi   void ldaddl(const Register& rs, const Register& rt, const MemOperand& src);
1515*f5c631daSSadaf Ebrahimi 
1516*f5c631daSSadaf Ebrahimi   // Atomic add on word or doubleword in memory, with Load-acquire and
1517*f5c631daSSadaf Ebrahimi   // Store-release semantics [Armv8.1]
1518*f5c631daSSadaf Ebrahimi   void ldaddal(const Register& rs, const Register& rt, const MemOperand& src);
1519*f5c631daSSadaf Ebrahimi 
1520*f5c631daSSadaf Ebrahimi   // Atomic bit clear on byte in memory [Armv8.1]
1521*f5c631daSSadaf Ebrahimi   void ldclrb(const Register& rs, const Register& rt, const MemOperand& src);
1522*f5c631daSSadaf Ebrahimi 
1523*f5c631daSSadaf Ebrahimi   // Atomic bit clear on byte in memory, with Load-acquire semantics [Armv8.1]
1524*f5c631daSSadaf Ebrahimi   void ldclrab(const Register& rs, const Register& rt, const MemOperand& src);
1525*f5c631daSSadaf Ebrahimi 
1526*f5c631daSSadaf Ebrahimi   // Atomic bit clear on byte in memory, with Store-release semantics [Armv8.1]
1527*f5c631daSSadaf Ebrahimi   void ldclrlb(const Register& rs, const Register& rt, const MemOperand& src);
1528*f5c631daSSadaf Ebrahimi 
1529*f5c631daSSadaf Ebrahimi   // Atomic bit clear on byte in memory, with Load-acquire and Store-release
1530*f5c631daSSadaf Ebrahimi   // semantics [Armv8.1]
1531*f5c631daSSadaf Ebrahimi   void ldclralb(const Register& rs, const Register& rt, const MemOperand& src);
1532*f5c631daSSadaf Ebrahimi 
1533*f5c631daSSadaf Ebrahimi   // Atomic bit clear on halfword in memory [Armv8.1]
1534*f5c631daSSadaf Ebrahimi   void ldclrh(const Register& rs, const Register& rt, const MemOperand& src);
1535*f5c631daSSadaf Ebrahimi 
1536*f5c631daSSadaf Ebrahimi   // Atomic bit clear on halfword in memory, with Load-acquire semantics
1537*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1538*f5c631daSSadaf Ebrahimi   void ldclrah(const Register& rs, const Register& rt, const MemOperand& src);
1539*f5c631daSSadaf Ebrahimi 
1540*f5c631daSSadaf Ebrahimi   // Atomic bit clear on halfword in memory, with Store-release semantics
1541*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1542*f5c631daSSadaf Ebrahimi   void ldclrlh(const Register& rs, const Register& rt, const MemOperand& src);
1543*f5c631daSSadaf Ebrahimi 
1544*f5c631daSSadaf Ebrahimi   // Atomic bit clear on halfword in memory, with Load-acquire and Store-release
1545*f5c631daSSadaf Ebrahimi   // semantics [Armv8.1]
1546*f5c631daSSadaf Ebrahimi   void ldclralh(const Register& rs, const Register& rt, const MemOperand& src);
1547*f5c631daSSadaf Ebrahimi 
1548*f5c631daSSadaf Ebrahimi   // Atomic bit clear on word or doubleword in memory [Armv8.1]
1549*f5c631daSSadaf Ebrahimi   void ldclr(const Register& rs, const Register& rt, const MemOperand& src);
1550*f5c631daSSadaf Ebrahimi 
1551*f5c631daSSadaf Ebrahimi   // Atomic bit clear on word or doubleword in memory, with Load-acquire
1552*f5c631daSSadaf Ebrahimi   // semantics [Armv8.1]
1553*f5c631daSSadaf Ebrahimi   void ldclra(const Register& rs, const Register& rt, const MemOperand& src);
1554*f5c631daSSadaf Ebrahimi 
1555*f5c631daSSadaf Ebrahimi   // Atomic bit clear on word or doubleword in memory, with Store-release
1556*f5c631daSSadaf Ebrahimi   // semantics [Armv8.1]
1557*f5c631daSSadaf Ebrahimi   void ldclrl(const Register& rs, const Register& rt, const MemOperand& src);
1558*f5c631daSSadaf Ebrahimi 
1559*f5c631daSSadaf Ebrahimi   // Atomic bit clear on word or doubleword in memory, with Load-acquire and
1560*f5c631daSSadaf Ebrahimi   // Store-release semantics [Armv8.1]
1561*f5c631daSSadaf Ebrahimi   void ldclral(const Register& rs, const Register& rt, const MemOperand& src);
1562*f5c631daSSadaf Ebrahimi 
1563*f5c631daSSadaf Ebrahimi   // Atomic exclusive OR on byte in memory [Armv8.1]
1564*f5c631daSSadaf Ebrahimi   void ldeorb(const Register& rs, const Register& rt, const MemOperand& src);
1565*f5c631daSSadaf Ebrahimi 
1566*f5c631daSSadaf Ebrahimi   // Atomic exclusive OR on byte in memory, with Load-acquire semantics
1567*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1568*f5c631daSSadaf Ebrahimi   void ldeorab(const Register& rs, const Register& rt, const MemOperand& src);
1569*f5c631daSSadaf Ebrahimi 
1570*f5c631daSSadaf Ebrahimi   // Atomic exclusive OR on byte in memory, with Store-release semantics
1571*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1572*f5c631daSSadaf Ebrahimi   void ldeorlb(const Register& rs, const Register& rt, const MemOperand& src);
1573*f5c631daSSadaf Ebrahimi 
1574*f5c631daSSadaf Ebrahimi   // Atomic exclusive OR on byte in memory, with Load-acquire and Store-release
1575*f5c631daSSadaf Ebrahimi   // semantics [Armv8.1]
1576*f5c631daSSadaf Ebrahimi   void ldeoralb(const Register& rs, const Register& rt, const MemOperand& src);
1577*f5c631daSSadaf Ebrahimi 
1578*f5c631daSSadaf Ebrahimi   // Atomic exclusive OR on halfword in memory [Armv8.1]
1579*f5c631daSSadaf Ebrahimi   void ldeorh(const Register& rs, const Register& rt, const MemOperand& src);
1580*f5c631daSSadaf Ebrahimi 
1581*f5c631daSSadaf Ebrahimi   // Atomic exclusive OR on halfword in memory, with Load-acquire semantics
1582*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1583*f5c631daSSadaf Ebrahimi   void ldeorah(const Register& rs, const Register& rt, const MemOperand& src);
1584*f5c631daSSadaf Ebrahimi 
1585*f5c631daSSadaf Ebrahimi   // Atomic exclusive OR on halfword in memory, with Store-release semantics
1586*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1587*f5c631daSSadaf Ebrahimi   void ldeorlh(const Register& rs, const Register& rt, const MemOperand& src);
1588*f5c631daSSadaf Ebrahimi 
1589*f5c631daSSadaf Ebrahimi   // Atomic exclusive OR on halfword in memory, with Load-acquire and
1590*f5c631daSSadaf Ebrahimi   // Store-release semantics [Armv8.1]
1591*f5c631daSSadaf Ebrahimi   void ldeoralh(const Register& rs, const Register& rt, const MemOperand& src);
1592*f5c631daSSadaf Ebrahimi 
1593*f5c631daSSadaf Ebrahimi   // Atomic exclusive OR on word or doubleword in memory [Armv8.1]
1594*f5c631daSSadaf Ebrahimi   void ldeor(const Register& rs, const Register& rt, const MemOperand& src);
1595*f5c631daSSadaf Ebrahimi 
1596*f5c631daSSadaf Ebrahimi   // Atomic exclusive OR on word or doubleword in memory, with Load-acquire
1597*f5c631daSSadaf Ebrahimi   // semantics [Armv8.1]
1598*f5c631daSSadaf Ebrahimi   void ldeora(const Register& rs, const Register& rt, const MemOperand& src);
1599*f5c631daSSadaf Ebrahimi 
1600*f5c631daSSadaf Ebrahimi   // Atomic exclusive OR on word or doubleword in memory, with Store-release
1601*f5c631daSSadaf Ebrahimi   // semantics [Armv8.1]
1602*f5c631daSSadaf Ebrahimi   void ldeorl(const Register& rs, const Register& rt, const MemOperand& src);
1603*f5c631daSSadaf Ebrahimi 
1604*f5c631daSSadaf Ebrahimi   // Atomic exclusive OR on word or doubleword in memory, with Load-acquire and
1605*f5c631daSSadaf Ebrahimi   // Store-release semantics [Armv8.1]
1606*f5c631daSSadaf Ebrahimi   void ldeoral(const Register& rs, const Register& rt, const MemOperand& src);
1607*f5c631daSSadaf Ebrahimi 
1608*f5c631daSSadaf Ebrahimi   // Atomic bit set on byte in memory [Armv8.1]
1609*f5c631daSSadaf Ebrahimi   void ldsetb(const Register& rs, const Register& rt, const MemOperand& src);
1610*f5c631daSSadaf Ebrahimi 
1611*f5c631daSSadaf Ebrahimi   // Atomic bit set on byte in memory, with Load-acquire semantics [Armv8.1]
1612*f5c631daSSadaf Ebrahimi   void ldsetab(const Register& rs, const Register& rt, const MemOperand& src);
1613*f5c631daSSadaf Ebrahimi 
1614*f5c631daSSadaf Ebrahimi   // Atomic bit set on byte in memory, with Store-release semantics [Armv8.1]
1615*f5c631daSSadaf Ebrahimi   void ldsetlb(const Register& rs, const Register& rt, const MemOperand& src);
1616*f5c631daSSadaf Ebrahimi 
1617*f5c631daSSadaf Ebrahimi   // Atomic bit set on byte in memory, with Load-acquire and Store-release
1618*f5c631daSSadaf Ebrahimi   // semantics [Armv8.1]
1619*f5c631daSSadaf Ebrahimi   void ldsetalb(const Register& rs, const Register& rt, const MemOperand& src);
1620*f5c631daSSadaf Ebrahimi 
1621*f5c631daSSadaf Ebrahimi   // Atomic bit set on halfword in memory [Armv8.1]
1622*f5c631daSSadaf Ebrahimi   void ldseth(const Register& rs, const Register& rt, const MemOperand& src);
1623*f5c631daSSadaf Ebrahimi 
1624*f5c631daSSadaf Ebrahimi   // Atomic bit set on halfword in memory, with Load-acquire semantics [Armv8.1]
1625*f5c631daSSadaf Ebrahimi   void ldsetah(const Register& rs, const Register& rt, const MemOperand& src);
1626*f5c631daSSadaf Ebrahimi 
1627*f5c631daSSadaf Ebrahimi   // Atomic bit set on halfword in memory, with Store-release semantics
1628*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1629*f5c631daSSadaf Ebrahimi   void ldsetlh(const Register& rs, const Register& rt, const MemOperand& src);
1630*f5c631daSSadaf Ebrahimi 
1631*f5c631daSSadaf Ebrahimi   // Atomic bit set on halfword in memory, with Load-acquire and Store-release
1632*f5c631daSSadaf Ebrahimi   // semantics [Armv8.1]
1633*f5c631daSSadaf Ebrahimi   void ldsetalh(const Register& rs, const Register& rt, const MemOperand& src);
1634*f5c631daSSadaf Ebrahimi 
1635*f5c631daSSadaf Ebrahimi   // Atomic bit set on word or doubleword in memory [Armv8.1]
1636*f5c631daSSadaf Ebrahimi   void ldset(const Register& rs, const Register& rt, const MemOperand& src);
1637*f5c631daSSadaf Ebrahimi 
1638*f5c631daSSadaf Ebrahimi   // Atomic bit set on word or doubleword in memory, with Load-acquire semantics
1639*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1640*f5c631daSSadaf Ebrahimi   void ldseta(const Register& rs, const Register& rt, const MemOperand& src);
1641*f5c631daSSadaf Ebrahimi 
1642*f5c631daSSadaf Ebrahimi   // Atomic bit set on word or doubleword in memory, with Store-release
1643*f5c631daSSadaf Ebrahimi   // semantics [Armv8.1]
1644*f5c631daSSadaf Ebrahimi   void ldsetl(const Register& rs, const Register& rt, const MemOperand& src);
1645*f5c631daSSadaf Ebrahimi 
1646*f5c631daSSadaf Ebrahimi   // Atomic bit set on word or doubleword in memory, with Load-acquire and
1647*f5c631daSSadaf Ebrahimi   // Store-release semantics [Armv8.1]
1648*f5c631daSSadaf Ebrahimi   void ldsetal(const Register& rs, const Register& rt, const MemOperand& src);
1649*f5c631daSSadaf Ebrahimi 
1650*f5c631daSSadaf Ebrahimi   // Atomic signed maximum on byte in memory [Armv8.1]
1651*f5c631daSSadaf Ebrahimi   void ldsmaxb(const Register& rs, const Register& rt, const MemOperand& src);
1652*f5c631daSSadaf Ebrahimi 
1653*f5c631daSSadaf Ebrahimi   // Atomic signed maximum on byte in memory, with Load-acquire semantics
1654*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1655*f5c631daSSadaf Ebrahimi   void ldsmaxab(const Register& rs, const Register& rt, const MemOperand& src);
1656*f5c631daSSadaf Ebrahimi 
1657*f5c631daSSadaf Ebrahimi   // Atomic signed maximum on byte in memory, with Store-release semantics
1658*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1659*f5c631daSSadaf Ebrahimi   void ldsmaxlb(const Register& rs, const Register& rt, const MemOperand& src);
1660*f5c631daSSadaf Ebrahimi 
1661*f5c631daSSadaf Ebrahimi   // Atomic signed maximum on byte in memory, with Load-acquire and
1662*f5c631daSSadaf Ebrahimi   // Store-release semantics [Armv8.1]
1663*f5c631daSSadaf Ebrahimi   void ldsmaxalb(const Register& rs, const Register& rt, const MemOperand& src);
1664*f5c631daSSadaf Ebrahimi 
1665*f5c631daSSadaf Ebrahimi   // Atomic signed maximum on halfword in memory [Armv8.1]
1666*f5c631daSSadaf Ebrahimi   void ldsmaxh(const Register& rs, const Register& rt, const MemOperand& src);
1667*f5c631daSSadaf Ebrahimi 
1668*f5c631daSSadaf Ebrahimi   // Atomic signed maximum on halfword in memory, with Load-acquire semantics
1669*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1670*f5c631daSSadaf Ebrahimi   void ldsmaxah(const Register& rs, const Register& rt, const MemOperand& src);
1671*f5c631daSSadaf Ebrahimi 
1672*f5c631daSSadaf Ebrahimi   // Atomic signed maximum on halfword in memory, with Store-release semantics
1673*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1674*f5c631daSSadaf Ebrahimi   void ldsmaxlh(const Register& rs, const Register& rt, const MemOperand& src);
1675*f5c631daSSadaf Ebrahimi 
1676*f5c631daSSadaf Ebrahimi   // Atomic signed maximum on halfword in memory, with Load-acquire and
1677*f5c631daSSadaf Ebrahimi   // Store-release semantics [Armv8.1]
1678*f5c631daSSadaf Ebrahimi   void ldsmaxalh(const Register& rs, const Register& rt, const MemOperand& src);
1679*f5c631daSSadaf Ebrahimi 
1680*f5c631daSSadaf Ebrahimi   // Atomic signed maximum on word or doubleword in memory [Armv8.1]
1681*f5c631daSSadaf Ebrahimi   void ldsmax(const Register& rs, const Register& rt, const MemOperand& src);
1682*f5c631daSSadaf Ebrahimi 
1683*f5c631daSSadaf Ebrahimi   // Atomic signed maximum on word or doubleword in memory, with Load-acquire
1684*f5c631daSSadaf Ebrahimi   // semantics [Armv8.1]
1685*f5c631daSSadaf Ebrahimi   void ldsmaxa(const Register& rs, const Register& rt, const MemOperand& src);
1686*f5c631daSSadaf Ebrahimi 
1687*f5c631daSSadaf Ebrahimi   // Atomic signed maximum on word or doubleword in memory, with Store-release
1688*f5c631daSSadaf Ebrahimi   // semantics [Armv8.1]
1689*f5c631daSSadaf Ebrahimi   void ldsmaxl(const Register& rs, const Register& rt, const MemOperand& src);
1690*f5c631daSSadaf Ebrahimi 
1691*f5c631daSSadaf Ebrahimi   // Atomic signed maximum on word or doubleword in memory, with Load-acquire
1692*f5c631daSSadaf Ebrahimi   // and Store-release semantics [Armv8.1]
1693*f5c631daSSadaf Ebrahimi   void ldsmaxal(const Register& rs, const Register& rt, const MemOperand& src);
1694*f5c631daSSadaf Ebrahimi 
1695*f5c631daSSadaf Ebrahimi   // Atomic signed minimum on byte in memory [Armv8.1]
1696*f5c631daSSadaf Ebrahimi   void ldsminb(const Register& rs, const Register& rt, const MemOperand& src);
1697*f5c631daSSadaf Ebrahimi 
1698*f5c631daSSadaf Ebrahimi   // Atomic signed minimum on byte in memory, with Load-acquire semantics
1699*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1700*f5c631daSSadaf Ebrahimi   void ldsminab(const Register& rs, const Register& rt, const MemOperand& src);
1701*f5c631daSSadaf Ebrahimi 
1702*f5c631daSSadaf Ebrahimi   // Atomic signed minimum on byte in memory, with Store-release semantics
1703*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1704*f5c631daSSadaf Ebrahimi   void ldsminlb(const Register& rs, const Register& rt, const MemOperand& src);
1705*f5c631daSSadaf Ebrahimi 
1706*f5c631daSSadaf Ebrahimi   // Atomic signed minimum on byte in memory, with Load-acquire and
1707*f5c631daSSadaf Ebrahimi   // Store-release semantics [Armv8.1]
1708*f5c631daSSadaf Ebrahimi   void ldsminalb(const Register& rs, const Register& rt, const MemOperand& src);
1709*f5c631daSSadaf Ebrahimi 
1710*f5c631daSSadaf Ebrahimi   // Atomic signed minimum on halfword in memory [Armv8.1]
1711*f5c631daSSadaf Ebrahimi   void ldsminh(const Register& rs, const Register& rt, const MemOperand& src);
1712*f5c631daSSadaf Ebrahimi 
1713*f5c631daSSadaf Ebrahimi   // Atomic signed minimum on halfword in memory, with Load-acquire semantics
1714*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1715*f5c631daSSadaf Ebrahimi   void ldsminah(const Register& rs, const Register& rt, const MemOperand& src);
1716*f5c631daSSadaf Ebrahimi 
1717*f5c631daSSadaf Ebrahimi   // Atomic signed minimum on halfword in memory, with Store-release semantics
1718*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1719*f5c631daSSadaf Ebrahimi   void ldsminlh(const Register& rs, const Register& rt, const MemOperand& src);
1720*f5c631daSSadaf Ebrahimi 
1721*f5c631daSSadaf Ebrahimi   // Atomic signed minimum on halfword in memory, with Load-acquire and
1722*f5c631daSSadaf Ebrahimi   // Store-release semantics [Armv8.1]
1723*f5c631daSSadaf Ebrahimi   void ldsminalh(const Register& rs, const Register& rt, const MemOperand& src);
1724*f5c631daSSadaf Ebrahimi 
1725*f5c631daSSadaf Ebrahimi   // Atomic signed minimum on word or doubleword in memory [Armv8.1]
1726*f5c631daSSadaf Ebrahimi   void ldsmin(const Register& rs, const Register& rt, const MemOperand& src);
1727*f5c631daSSadaf Ebrahimi 
1728*f5c631daSSadaf Ebrahimi   // Atomic signed minimum on word or doubleword in memory, with Load-acquire
1729*f5c631daSSadaf Ebrahimi   // semantics [Armv8.1]
1730*f5c631daSSadaf Ebrahimi   void ldsmina(const Register& rs, const Register& rt, const MemOperand& src);
1731*f5c631daSSadaf Ebrahimi 
1732*f5c631daSSadaf Ebrahimi   // Atomic signed minimum on word or doubleword in memory, with Store-release
1733*f5c631daSSadaf Ebrahimi   // semantics [Armv8.1]
1734*f5c631daSSadaf Ebrahimi   void ldsminl(const Register& rs, const Register& rt, const MemOperand& src);
1735*f5c631daSSadaf Ebrahimi 
1736*f5c631daSSadaf Ebrahimi   // Atomic signed minimum on word or doubleword in memory, with Load-acquire
1737*f5c631daSSadaf Ebrahimi   // and Store-release semantics [Armv8.1]
1738*f5c631daSSadaf Ebrahimi   void ldsminal(const Register& rs, const Register& rt, const MemOperand& src);
1739*f5c631daSSadaf Ebrahimi 
1740*f5c631daSSadaf Ebrahimi   // Atomic unsigned maximum on byte in memory [Armv8.1]
1741*f5c631daSSadaf Ebrahimi   void ldumaxb(const Register& rs, const Register& rt, const MemOperand& src);
1742*f5c631daSSadaf Ebrahimi 
1743*f5c631daSSadaf Ebrahimi   // Atomic unsigned maximum on byte in memory, with Load-acquire semantics
1744*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1745*f5c631daSSadaf Ebrahimi   void ldumaxab(const Register& rs, const Register& rt, const MemOperand& src);
1746*f5c631daSSadaf Ebrahimi 
1747*f5c631daSSadaf Ebrahimi   // Atomic unsigned maximum on byte in memory, with Store-release semantics
1748*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1749*f5c631daSSadaf Ebrahimi   void ldumaxlb(const Register& rs, const Register& rt, const MemOperand& src);
1750*f5c631daSSadaf Ebrahimi 
1751*f5c631daSSadaf Ebrahimi   // Atomic unsigned maximum on byte in memory, with Load-acquire and
1752*f5c631daSSadaf Ebrahimi   // Store-release semantics [Armv8.1]
1753*f5c631daSSadaf Ebrahimi   void ldumaxalb(const Register& rs, const Register& rt, const MemOperand& src);
1754*f5c631daSSadaf Ebrahimi 
1755*f5c631daSSadaf Ebrahimi   // Atomic unsigned maximum on halfword in memory [Armv8.1]
1756*f5c631daSSadaf Ebrahimi   void ldumaxh(const Register& rs, const Register& rt, const MemOperand& src);
1757*f5c631daSSadaf Ebrahimi 
1758*f5c631daSSadaf Ebrahimi   // Atomic unsigned maximum on halfword in memory, with Load-acquire semantics
1759*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1760*f5c631daSSadaf Ebrahimi   void ldumaxah(const Register& rs, const Register& rt, const MemOperand& src);
1761*f5c631daSSadaf Ebrahimi 
1762*f5c631daSSadaf Ebrahimi   // Atomic unsigned maximum on halfword in memory, with Store-release semantics
1763*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1764*f5c631daSSadaf Ebrahimi   void ldumaxlh(const Register& rs, const Register& rt, const MemOperand& src);
1765*f5c631daSSadaf Ebrahimi 
1766*f5c631daSSadaf Ebrahimi   // Atomic unsigned maximum on halfword in memory, with Load-acquire and
1767*f5c631daSSadaf Ebrahimi   // Store-release semantics [Armv8.1]
1768*f5c631daSSadaf Ebrahimi   void ldumaxalh(const Register& rs, const Register& rt, const MemOperand& src);
1769*f5c631daSSadaf Ebrahimi 
1770*f5c631daSSadaf Ebrahimi   // Atomic unsigned maximum on word or doubleword in memory [Armv8.1]
1771*f5c631daSSadaf Ebrahimi   void ldumax(const Register& rs, const Register& rt, const MemOperand& src);
1772*f5c631daSSadaf Ebrahimi 
1773*f5c631daSSadaf Ebrahimi   // Atomic unsigned maximum on word or doubleword in memory, with Load-acquire
1774*f5c631daSSadaf Ebrahimi   // semantics [Armv8.1]
1775*f5c631daSSadaf Ebrahimi   void ldumaxa(const Register& rs, const Register& rt, const MemOperand& src);
1776*f5c631daSSadaf Ebrahimi 
1777*f5c631daSSadaf Ebrahimi   // Atomic unsigned maximum on word or doubleword in memory, with Store-release
1778*f5c631daSSadaf Ebrahimi   // semantics [Armv8.1]
1779*f5c631daSSadaf Ebrahimi   void ldumaxl(const Register& rs, const Register& rt, const MemOperand& src);
1780*f5c631daSSadaf Ebrahimi 
1781*f5c631daSSadaf Ebrahimi   // Atomic unsigned maximum on word or doubleword in memory, with Load-acquire
1782*f5c631daSSadaf Ebrahimi   // and Store-release semantics [Armv8.1]
1783*f5c631daSSadaf Ebrahimi   void ldumaxal(const Register& rs, const Register& rt, const MemOperand& src);
1784*f5c631daSSadaf Ebrahimi 
1785*f5c631daSSadaf Ebrahimi   // Atomic unsigned minimum on byte in memory [Armv8.1]
1786*f5c631daSSadaf Ebrahimi   void lduminb(const Register& rs, const Register& rt, const MemOperand& src);
1787*f5c631daSSadaf Ebrahimi 
1788*f5c631daSSadaf Ebrahimi   // Atomic unsigned minimum on byte in memory, with Load-acquire semantics
1789*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1790*f5c631daSSadaf Ebrahimi   void lduminab(const Register& rs, const Register& rt, const MemOperand& src);
1791*f5c631daSSadaf Ebrahimi 
1792*f5c631daSSadaf Ebrahimi   // Atomic unsigned minimum on byte in memory, with Store-release semantics
1793*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1794*f5c631daSSadaf Ebrahimi   void lduminlb(const Register& rs, const Register& rt, const MemOperand& src);
1795*f5c631daSSadaf Ebrahimi 
1796*f5c631daSSadaf Ebrahimi   // Atomic unsigned minimum on byte in memory, with Load-acquire and
1797*f5c631daSSadaf Ebrahimi   // Store-release semantics [Armv8.1]
1798*f5c631daSSadaf Ebrahimi   void lduminalb(const Register& rs, const Register& rt, const MemOperand& src);
1799*f5c631daSSadaf Ebrahimi 
1800*f5c631daSSadaf Ebrahimi   // Atomic unsigned minimum on halfword in memory [Armv8.1]
1801*f5c631daSSadaf Ebrahimi   void lduminh(const Register& rs, const Register& rt, const MemOperand& src);
1802*f5c631daSSadaf Ebrahimi 
1803*f5c631daSSadaf Ebrahimi   // Atomic unsigned minimum on halfword in memory, with Load-acquire semantics
1804*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1805*f5c631daSSadaf Ebrahimi   void lduminah(const Register& rs, const Register& rt, const MemOperand& src);
1806*f5c631daSSadaf Ebrahimi 
1807*f5c631daSSadaf Ebrahimi   // Atomic unsigned minimum on halfword in memory, with Store-release semantics
1808*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1809*f5c631daSSadaf Ebrahimi   void lduminlh(const Register& rs, const Register& rt, const MemOperand& src);
1810*f5c631daSSadaf Ebrahimi 
1811*f5c631daSSadaf Ebrahimi   // Atomic unsigned minimum on halfword in memory, with Load-acquire and
1812*f5c631daSSadaf Ebrahimi   // Store-release semantics [Armv8.1]
1813*f5c631daSSadaf Ebrahimi   void lduminalh(const Register& rs, const Register& rt, const MemOperand& src);
1814*f5c631daSSadaf Ebrahimi 
1815*f5c631daSSadaf Ebrahimi   // Atomic unsigned minimum on word or doubleword in memory [Armv8.1]
1816*f5c631daSSadaf Ebrahimi   void ldumin(const Register& rs, const Register& rt, const MemOperand& src);
1817*f5c631daSSadaf Ebrahimi 
1818*f5c631daSSadaf Ebrahimi   // Atomic unsigned minimum on word or doubleword in memory, with Load-acquire
1819*f5c631daSSadaf Ebrahimi   // semantics [Armv8.1]
1820*f5c631daSSadaf Ebrahimi   void ldumina(const Register& rs, const Register& rt, const MemOperand& src);
1821*f5c631daSSadaf Ebrahimi 
1822*f5c631daSSadaf Ebrahimi   // Atomic unsigned minimum on word or doubleword in memory, with Store-release
1823*f5c631daSSadaf Ebrahimi   // semantics [Armv8.1]
1824*f5c631daSSadaf Ebrahimi   void lduminl(const Register& rs, const Register& rt, const MemOperand& src);
1825*f5c631daSSadaf Ebrahimi 
1826*f5c631daSSadaf Ebrahimi   // Atomic unsigned minimum on word or doubleword in memory, with Load-acquire
1827*f5c631daSSadaf Ebrahimi   // and Store-release semantics [Armv8.1]
1828*f5c631daSSadaf Ebrahimi   void lduminal(const Register& rs, const Register& rt, const MemOperand& src);
1829*f5c631daSSadaf Ebrahimi 
1830*f5c631daSSadaf Ebrahimi   // Atomic add on byte in memory, without return. [Armv8.1]
1831*f5c631daSSadaf Ebrahimi   void staddb(const Register& rs, const MemOperand& src);
1832*f5c631daSSadaf Ebrahimi 
1833*f5c631daSSadaf Ebrahimi   // Atomic add on byte in memory, with Store-release semantics and without
1834*f5c631daSSadaf Ebrahimi   // return. [Armv8.1]
1835*f5c631daSSadaf Ebrahimi   void staddlb(const Register& rs, const MemOperand& src);
1836*f5c631daSSadaf Ebrahimi 
1837*f5c631daSSadaf Ebrahimi   // Atomic add on halfword in memory, without return. [Armv8.1]
1838*f5c631daSSadaf Ebrahimi   void staddh(const Register& rs, const MemOperand& src);
1839*f5c631daSSadaf Ebrahimi 
1840*f5c631daSSadaf Ebrahimi   // Atomic add on halfword in memory, with Store-release semantics and without
1841*f5c631daSSadaf Ebrahimi   // return. [Armv8.1]
1842*f5c631daSSadaf Ebrahimi   void staddlh(const Register& rs, const MemOperand& src);
1843*f5c631daSSadaf Ebrahimi 
1844*f5c631daSSadaf Ebrahimi   // Atomic add on word or doubleword in memory, without return. [Armv8.1]
1845*f5c631daSSadaf Ebrahimi   void stadd(const Register& rs, const MemOperand& src);
1846*f5c631daSSadaf Ebrahimi 
1847*f5c631daSSadaf Ebrahimi   // Atomic add on word or doubleword in memory, with Store-release semantics
1848*f5c631daSSadaf Ebrahimi   // and without return. [Armv8.1]
1849*f5c631daSSadaf Ebrahimi   void staddl(const Register& rs, const MemOperand& src);
1850*f5c631daSSadaf Ebrahimi 
1851*f5c631daSSadaf Ebrahimi   // Atomic bit clear on byte in memory, without return. [Armv8.1]
1852*f5c631daSSadaf Ebrahimi   void stclrb(const Register& rs, const MemOperand& src);
1853*f5c631daSSadaf Ebrahimi 
1854*f5c631daSSadaf Ebrahimi   // Atomic bit clear on byte in memory, with Store-release semantics and
1855*f5c631daSSadaf Ebrahimi   // without return. [Armv8.1]
1856*f5c631daSSadaf Ebrahimi   void stclrlb(const Register& rs, const MemOperand& src);
1857*f5c631daSSadaf Ebrahimi 
1858*f5c631daSSadaf Ebrahimi   // Atomic bit clear on halfword in memory, without return. [Armv8.1]
1859*f5c631daSSadaf Ebrahimi   void stclrh(const Register& rs, const MemOperand& src);
1860*f5c631daSSadaf Ebrahimi 
1861*f5c631daSSadaf Ebrahimi   // Atomic bit clear on halfword in memory, with Store-release semantics and
1862*f5c631daSSadaf Ebrahimi   // without return. [Armv8.1]
1863*f5c631daSSadaf Ebrahimi   void stclrlh(const Register& rs, const MemOperand& src);
1864*f5c631daSSadaf Ebrahimi 
1865*f5c631daSSadaf Ebrahimi   // Atomic bit clear on word or doubleword in memory, without return. [Armv8.1]
1866*f5c631daSSadaf Ebrahimi   void stclr(const Register& rs, const MemOperand& src);
1867*f5c631daSSadaf Ebrahimi 
1868*f5c631daSSadaf Ebrahimi   // Atomic bit clear on word or doubleword in memory, with Store-release
1869*f5c631daSSadaf Ebrahimi   // semantics and without return. [Armv8.1]
1870*f5c631daSSadaf Ebrahimi   void stclrl(const Register& rs, const MemOperand& src);
1871*f5c631daSSadaf Ebrahimi 
1872*f5c631daSSadaf Ebrahimi   // Atomic exclusive OR on byte in memory, without return. [Armv8.1]
1873*f5c631daSSadaf Ebrahimi   void steorb(const Register& rs, const MemOperand& src);
1874*f5c631daSSadaf Ebrahimi 
1875*f5c631daSSadaf Ebrahimi   // Atomic exclusive OR on byte in memory, with Store-release semantics and
1876*f5c631daSSadaf Ebrahimi   // without return. [Armv8.1]
1877*f5c631daSSadaf Ebrahimi   void steorlb(const Register& rs, const MemOperand& src);
1878*f5c631daSSadaf Ebrahimi 
1879*f5c631daSSadaf Ebrahimi   // Atomic exclusive OR on halfword in memory, without return. [Armv8.1]
1880*f5c631daSSadaf Ebrahimi   void steorh(const Register& rs, const MemOperand& src);
1881*f5c631daSSadaf Ebrahimi 
1882*f5c631daSSadaf Ebrahimi   // Atomic exclusive OR on halfword in memory, with Store-release semantics
1883*f5c631daSSadaf Ebrahimi   // and without return. [Armv8.1]
1884*f5c631daSSadaf Ebrahimi   void steorlh(const Register& rs, const MemOperand& src);
1885*f5c631daSSadaf Ebrahimi 
1886*f5c631daSSadaf Ebrahimi   // Atomic exclusive OR on word or doubleword in memory, without return.
1887*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1888*f5c631daSSadaf Ebrahimi   void steor(const Register& rs, const MemOperand& src);
1889*f5c631daSSadaf Ebrahimi 
1890*f5c631daSSadaf Ebrahimi   // Atomic exclusive OR on word or doubleword in memory, with Store-release
1891*f5c631daSSadaf Ebrahimi   // semantics and without return. [Armv8.1]
1892*f5c631daSSadaf Ebrahimi   void steorl(const Register& rs, const MemOperand& src);
1893*f5c631daSSadaf Ebrahimi 
1894*f5c631daSSadaf Ebrahimi   // Atomic bit set on byte in memory, without return. [Armv8.1]
1895*f5c631daSSadaf Ebrahimi   void stsetb(const Register& rs, const MemOperand& src);
1896*f5c631daSSadaf Ebrahimi 
1897*f5c631daSSadaf Ebrahimi   // Atomic bit set on byte in memory, with Store-release semantics and without
1898*f5c631daSSadaf Ebrahimi   // return. [Armv8.1]
1899*f5c631daSSadaf Ebrahimi   void stsetlb(const Register& rs, const MemOperand& src);
1900*f5c631daSSadaf Ebrahimi 
1901*f5c631daSSadaf Ebrahimi   // Atomic bit set on halfword in memory, without return. [Armv8.1]
1902*f5c631daSSadaf Ebrahimi   void stseth(const Register& rs, const MemOperand& src);
1903*f5c631daSSadaf Ebrahimi 
1904*f5c631daSSadaf Ebrahimi   // Atomic bit set on halfword in memory, with Store-release semantics and
1905*f5c631daSSadaf Ebrahimi   // without return. [Armv8.1]
1906*f5c631daSSadaf Ebrahimi   void stsetlh(const Register& rs, const MemOperand& src);
1907*f5c631daSSadaf Ebrahimi 
1908*f5c631daSSadaf Ebrahimi   // Atomic bit set on word or doubleword in memory, without return. [Armv8.1]
1909*f5c631daSSadaf Ebrahimi   void stset(const Register& rs, const MemOperand& src);
1910*f5c631daSSadaf Ebrahimi 
1911*f5c631daSSadaf Ebrahimi   // Atomic bit set on word or doubleword in memory, with Store-release
1912*f5c631daSSadaf Ebrahimi   // semantics and without return. [Armv8.1]
1913*f5c631daSSadaf Ebrahimi   void stsetl(const Register& rs, const MemOperand& src);
1914*f5c631daSSadaf Ebrahimi 
1915*f5c631daSSadaf Ebrahimi   // Atomic signed maximum on byte in memory, without return. [Armv8.1]
1916*f5c631daSSadaf Ebrahimi   void stsmaxb(const Register& rs, const MemOperand& src);
1917*f5c631daSSadaf Ebrahimi 
1918*f5c631daSSadaf Ebrahimi   // Atomic signed maximum on byte in memory, with Store-release semantics and
1919*f5c631daSSadaf Ebrahimi   // without return. [Armv8.1]
1920*f5c631daSSadaf Ebrahimi   void stsmaxlb(const Register& rs, const MemOperand& src);
1921*f5c631daSSadaf Ebrahimi 
1922*f5c631daSSadaf Ebrahimi   // Atomic signed maximum on halfword in memory, without return. [Armv8.1]
1923*f5c631daSSadaf Ebrahimi   void stsmaxh(const Register& rs, const MemOperand& src);
1924*f5c631daSSadaf Ebrahimi 
1925*f5c631daSSadaf Ebrahimi   // Atomic signed maximum on halfword in memory, with Store-release semantics
1926*f5c631daSSadaf Ebrahimi   // and without return. [Armv8.1]
1927*f5c631daSSadaf Ebrahimi   void stsmaxlh(const Register& rs, const MemOperand& src);
1928*f5c631daSSadaf Ebrahimi 
1929*f5c631daSSadaf Ebrahimi   // Atomic signed maximum on word or doubleword in memory, without return.
1930*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1931*f5c631daSSadaf Ebrahimi   void stsmax(const Register& rs, const MemOperand& src);
1932*f5c631daSSadaf Ebrahimi 
1933*f5c631daSSadaf Ebrahimi   // Atomic signed maximum on word or doubleword in memory, with Store-release
1934*f5c631daSSadaf Ebrahimi   // semantics and without return. [Armv8.1]
1935*f5c631daSSadaf Ebrahimi   void stsmaxl(const Register& rs, const MemOperand& src);
1936*f5c631daSSadaf Ebrahimi 
1937*f5c631daSSadaf Ebrahimi   // Atomic signed minimum on byte in memory, without return. [Armv8.1]
1938*f5c631daSSadaf Ebrahimi   void stsminb(const Register& rs, const MemOperand& src);
1939*f5c631daSSadaf Ebrahimi 
1940*f5c631daSSadaf Ebrahimi   // Atomic signed minimum on byte in memory, with Store-release semantics and
1941*f5c631daSSadaf Ebrahimi   // without return. [Armv8.1]
1942*f5c631daSSadaf Ebrahimi   void stsminlb(const Register& rs, const MemOperand& src);
1943*f5c631daSSadaf Ebrahimi 
1944*f5c631daSSadaf Ebrahimi   // Atomic signed minimum on halfword in memory, without return. [Armv8.1]
1945*f5c631daSSadaf Ebrahimi   void stsminh(const Register& rs, const MemOperand& src);
1946*f5c631daSSadaf Ebrahimi 
1947*f5c631daSSadaf Ebrahimi   // Atomic signed minimum on halfword in memory, with Store-release semantics
1948*f5c631daSSadaf Ebrahimi   // and without return. [Armv8.1]
1949*f5c631daSSadaf Ebrahimi   void stsminlh(const Register& rs, const MemOperand& src);
1950*f5c631daSSadaf Ebrahimi 
1951*f5c631daSSadaf Ebrahimi   // Atomic signed minimum on word or doubleword in memory, without return.
1952*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1953*f5c631daSSadaf Ebrahimi   void stsmin(const Register& rs, const MemOperand& src);
1954*f5c631daSSadaf Ebrahimi 
1955*f5c631daSSadaf Ebrahimi   // Atomic signed minimum on word or doubleword in memory, with Store-release
1956*f5c631daSSadaf Ebrahimi   // semantics and without return. semantics [Armv8.1]
1957*f5c631daSSadaf Ebrahimi   void stsminl(const Register& rs, const MemOperand& src);
1958*f5c631daSSadaf Ebrahimi 
1959*f5c631daSSadaf Ebrahimi   // Atomic unsigned maximum on byte in memory, without return. [Armv8.1]
1960*f5c631daSSadaf Ebrahimi   void stumaxb(const Register& rs, const MemOperand& src);
1961*f5c631daSSadaf Ebrahimi 
1962*f5c631daSSadaf Ebrahimi   // Atomic unsigned maximum on byte in memory, with Store-release semantics and
1963*f5c631daSSadaf Ebrahimi   // without return. [Armv8.1]
1964*f5c631daSSadaf Ebrahimi   void stumaxlb(const Register& rs, const MemOperand& src);
1965*f5c631daSSadaf Ebrahimi 
1966*f5c631daSSadaf Ebrahimi   // Atomic unsigned maximum on halfword in memory, without return. [Armv8.1]
1967*f5c631daSSadaf Ebrahimi   void stumaxh(const Register& rs, const MemOperand& src);
1968*f5c631daSSadaf Ebrahimi 
1969*f5c631daSSadaf Ebrahimi   // Atomic unsigned maximum on halfword in memory, with Store-release semantics
1970*f5c631daSSadaf Ebrahimi   // and without return. [Armv8.1]
1971*f5c631daSSadaf Ebrahimi   void stumaxlh(const Register& rs, const MemOperand& src);
1972*f5c631daSSadaf Ebrahimi 
1973*f5c631daSSadaf Ebrahimi   // Atomic unsigned maximum on word or doubleword in memory, without return.
1974*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1975*f5c631daSSadaf Ebrahimi   void stumax(const Register& rs, const MemOperand& src);
1976*f5c631daSSadaf Ebrahimi 
1977*f5c631daSSadaf Ebrahimi   // Atomic unsigned maximum on word or doubleword in memory, with Store-release
1978*f5c631daSSadaf Ebrahimi   // semantics and without return. [Armv8.1]
1979*f5c631daSSadaf Ebrahimi   void stumaxl(const Register& rs, const MemOperand& src);
1980*f5c631daSSadaf Ebrahimi 
1981*f5c631daSSadaf Ebrahimi   // Atomic unsigned minimum on byte in memory, without return. [Armv8.1]
1982*f5c631daSSadaf Ebrahimi   void stuminb(const Register& rs, const MemOperand& src);
1983*f5c631daSSadaf Ebrahimi 
1984*f5c631daSSadaf Ebrahimi   // Atomic unsigned minimum on byte in memory, with Store-release semantics and
1985*f5c631daSSadaf Ebrahimi   // without return. [Armv8.1]
1986*f5c631daSSadaf Ebrahimi   void stuminlb(const Register& rs, const MemOperand& src);
1987*f5c631daSSadaf Ebrahimi 
1988*f5c631daSSadaf Ebrahimi   // Atomic unsigned minimum on halfword in memory, without return. [Armv8.1]
1989*f5c631daSSadaf Ebrahimi   void stuminh(const Register& rs, const MemOperand& src);
1990*f5c631daSSadaf Ebrahimi 
1991*f5c631daSSadaf Ebrahimi   // Atomic unsigned minimum on halfword in memory, with Store-release semantics
1992*f5c631daSSadaf Ebrahimi   // and without return. [Armv8.1]
1993*f5c631daSSadaf Ebrahimi   void stuminlh(const Register& rs, const MemOperand& src);
1994*f5c631daSSadaf Ebrahimi 
1995*f5c631daSSadaf Ebrahimi   // Atomic unsigned minimum on word or doubleword in memory, without return.
1996*f5c631daSSadaf Ebrahimi   // [Armv8.1]
1997*f5c631daSSadaf Ebrahimi   void stumin(const Register& rs, const MemOperand& src);
1998*f5c631daSSadaf Ebrahimi 
1999*f5c631daSSadaf Ebrahimi   // Atomic unsigned minimum on word or doubleword in memory, with Store-release
2000*f5c631daSSadaf Ebrahimi   // semantics and without return. [Armv8.1]
2001*f5c631daSSadaf Ebrahimi   void stuminl(const Register& rs, const MemOperand& src);
2002*f5c631daSSadaf Ebrahimi 
2003*f5c631daSSadaf Ebrahimi   // Swap byte in memory [Armv8.1]
2004*f5c631daSSadaf Ebrahimi   void swpb(const Register& rs, const Register& rt, const MemOperand& src);
2005*f5c631daSSadaf Ebrahimi 
2006*f5c631daSSadaf Ebrahimi   // Swap byte in memory, with Load-acquire semantics [Armv8.1]
2007*f5c631daSSadaf Ebrahimi   void swpab(const Register& rs, const Register& rt, const MemOperand& src);
2008*f5c631daSSadaf Ebrahimi 
2009*f5c631daSSadaf Ebrahimi   // Swap byte in memory, with Store-release semantics [Armv8.1]
2010*f5c631daSSadaf Ebrahimi   void swplb(const Register& rs, const Register& rt, const MemOperand& src);
2011*f5c631daSSadaf Ebrahimi 
2012*f5c631daSSadaf Ebrahimi   // Swap byte in memory, with Load-acquire and Store-release semantics
2013*f5c631daSSadaf Ebrahimi   // [Armv8.1]
2014*f5c631daSSadaf Ebrahimi   void swpalb(const Register& rs, const Register& rt, const MemOperand& src);
2015*f5c631daSSadaf Ebrahimi 
2016*f5c631daSSadaf Ebrahimi   // Swap halfword in memory [Armv8.1]
2017*f5c631daSSadaf Ebrahimi   void swph(const Register& rs, const Register& rt, const MemOperand& src);
2018*f5c631daSSadaf Ebrahimi 
2019*f5c631daSSadaf Ebrahimi   // Swap halfword in memory, with Load-acquire semantics [Armv8.1]
2020*f5c631daSSadaf Ebrahimi   void swpah(const Register& rs, const Register& rt, const MemOperand& src);
2021*f5c631daSSadaf Ebrahimi 
2022*f5c631daSSadaf Ebrahimi   // Swap halfword in memory, with Store-release semantics [Armv8.1]
2023*f5c631daSSadaf Ebrahimi   void swplh(const Register& rs, const Register& rt, const MemOperand& src);
2024*f5c631daSSadaf Ebrahimi 
2025*f5c631daSSadaf Ebrahimi   // Swap halfword in memory, with Load-acquire and Store-release semantics
2026*f5c631daSSadaf Ebrahimi   // [Armv8.1]
2027*f5c631daSSadaf Ebrahimi   void swpalh(const Register& rs, const Register& rt, const MemOperand& src);
2028*f5c631daSSadaf Ebrahimi 
2029*f5c631daSSadaf Ebrahimi   // Swap word or doubleword in memory [Armv8.1]
2030*f5c631daSSadaf Ebrahimi   void swp(const Register& rs, const Register& rt, const MemOperand& src);
2031*f5c631daSSadaf Ebrahimi 
2032*f5c631daSSadaf Ebrahimi   // Swap word or doubleword in memory, with Load-acquire semantics [Armv8.1]
2033*f5c631daSSadaf Ebrahimi   void swpa(const Register& rs, const Register& rt, const MemOperand& src);
2034*f5c631daSSadaf Ebrahimi 
2035*f5c631daSSadaf Ebrahimi   // Swap word or doubleword in memory, with Store-release semantics [Armv8.1]
2036*f5c631daSSadaf Ebrahimi   void swpl(const Register& rs, const Register& rt, const MemOperand& src);
2037*f5c631daSSadaf Ebrahimi 
2038*f5c631daSSadaf Ebrahimi   // Swap word or doubleword in memory, with Load-acquire and Store-release
2039*f5c631daSSadaf Ebrahimi   // semantics [Armv8.1]
2040*f5c631daSSadaf Ebrahimi   void swpal(const Register& rs, const Register& rt, const MemOperand& src);
2041*f5c631daSSadaf Ebrahimi 
2042*f5c631daSSadaf Ebrahimi   // Load-Acquire RCpc Register byte [Armv8.3]
2043*f5c631daSSadaf Ebrahimi   void ldaprb(const Register& rt, const MemOperand& src);
2044*f5c631daSSadaf Ebrahimi 
2045*f5c631daSSadaf Ebrahimi   // Load-Acquire RCpc Register halfword [Armv8.3]
2046*f5c631daSSadaf Ebrahimi   void ldaprh(const Register& rt, const MemOperand& src);
2047*f5c631daSSadaf Ebrahimi 
2048*f5c631daSSadaf Ebrahimi   // Load-Acquire RCpc Register word or doubleword [Armv8.3]
2049*f5c631daSSadaf Ebrahimi   void ldapr(const Register& rt, const MemOperand& src);
2050*f5c631daSSadaf Ebrahimi 
2051*f5c631daSSadaf Ebrahimi   // Prefetch memory.
2052*f5c631daSSadaf Ebrahimi   void prfm(PrefetchOperation op,
2053*f5c631daSSadaf Ebrahimi             const MemOperand& addr,
2054*f5c631daSSadaf Ebrahimi             LoadStoreScalingOption option = PreferScaledOffset);
2055*f5c631daSSadaf Ebrahimi 
2056*f5c631daSSadaf Ebrahimi   // Prefetch memory (with unscaled offset).
2057*f5c631daSSadaf Ebrahimi   void prfum(PrefetchOperation op,
2058*f5c631daSSadaf Ebrahimi              const MemOperand& addr,
2059*f5c631daSSadaf Ebrahimi              LoadStoreScalingOption option = PreferUnscaledOffset);
2060*f5c631daSSadaf Ebrahimi 
2061*f5c631daSSadaf Ebrahimi   // Prefetch memory in the literal pool.
2062*f5c631daSSadaf Ebrahimi   void prfm(PrefetchOperation op, RawLiteral* literal);
2063*f5c631daSSadaf Ebrahimi 
2064*f5c631daSSadaf Ebrahimi   // Prefetch from pc + imm19 << 2.
2065*f5c631daSSadaf Ebrahimi   void prfm(PrefetchOperation op, int64_t imm19);
2066*f5c631daSSadaf Ebrahimi 
2067*f5c631daSSadaf Ebrahimi   // Prefetch memory (allowing unallocated hints).
2068*f5c631daSSadaf Ebrahimi   void prfm(int op,
2069*f5c631daSSadaf Ebrahimi             const MemOperand& addr,
2070*f5c631daSSadaf Ebrahimi             LoadStoreScalingOption option = PreferScaledOffset);
2071*f5c631daSSadaf Ebrahimi 
2072*f5c631daSSadaf Ebrahimi   // Prefetch memory (with unscaled offset, allowing unallocated hints).
2073*f5c631daSSadaf Ebrahimi   void prfum(int op,
2074*f5c631daSSadaf Ebrahimi              const MemOperand& addr,
2075*f5c631daSSadaf Ebrahimi              LoadStoreScalingOption option = PreferUnscaledOffset);
2076*f5c631daSSadaf Ebrahimi 
2077*f5c631daSSadaf Ebrahimi   // Prefetch memory in the literal pool (allowing unallocated hints).
2078*f5c631daSSadaf Ebrahimi   void prfm(int op, RawLiteral* literal);
2079*f5c631daSSadaf Ebrahimi 
2080*f5c631daSSadaf Ebrahimi   // Prefetch from pc + imm19 << 2 (allowing unallocated hints).
2081*f5c631daSSadaf Ebrahimi   void prfm(int op, int64_t imm19);
2082*f5c631daSSadaf Ebrahimi 
2083*f5c631daSSadaf Ebrahimi   // Move instructions. The default shift of -1 indicates that the move
2084*f5c631daSSadaf Ebrahimi   // instruction will calculate an appropriate 16-bit immediate and left shift
2085*f5c631daSSadaf Ebrahimi   // that is equal to the 64-bit immediate argument. If an explicit left shift
2086*f5c631daSSadaf Ebrahimi   // is specified (0, 16, 32 or 48), the immediate must be a 16-bit value.
2087*f5c631daSSadaf Ebrahimi   //
2088*f5c631daSSadaf Ebrahimi   // For movk, an explicit shift can be used to indicate which half word should
2089*f5c631daSSadaf Ebrahimi   // be overwritten, eg. movk(x0, 0, 0) will overwrite the least-significant
2090*f5c631daSSadaf Ebrahimi   // half word with zero, whereas movk(x0, 0, 48) will overwrite the
2091*f5c631daSSadaf Ebrahimi   // most-significant.
2092*f5c631daSSadaf Ebrahimi 
2093*f5c631daSSadaf Ebrahimi   // Move immediate and keep.
2094*f5c631daSSadaf Ebrahimi   void movk(const Register& rd, uint64_t imm, int shift = -1) {
2095*f5c631daSSadaf Ebrahimi     MoveWide(rd, imm, shift, MOVK);
2096*f5c631daSSadaf Ebrahimi   }
2097*f5c631daSSadaf Ebrahimi 
2098*f5c631daSSadaf Ebrahimi   // Move inverted immediate.
2099*f5c631daSSadaf Ebrahimi   void movn(const Register& rd, uint64_t imm, int shift = -1) {
2100*f5c631daSSadaf Ebrahimi     MoveWide(rd, imm, shift, MOVN);
2101*f5c631daSSadaf Ebrahimi   }
2102*f5c631daSSadaf Ebrahimi 
2103*f5c631daSSadaf Ebrahimi   // Move immediate.
2104*f5c631daSSadaf Ebrahimi   void movz(const Register& rd, uint64_t imm, int shift = -1) {
2105*f5c631daSSadaf Ebrahimi     MoveWide(rd, imm, shift, MOVZ);
2106*f5c631daSSadaf Ebrahimi   }
2107*f5c631daSSadaf Ebrahimi 
2108*f5c631daSSadaf Ebrahimi   // Move immediate, aliases for movz, movn, orr.
mov(const Register & rd,uint64_t imm)2109*f5c631daSSadaf Ebrahimi   void mov(const Register& rd, uint64_t imm) {
2110*f5c631daSSadaf Ebrahimi     if (!OneInstrMoveImmediateHelper(this, rd, imm)) {
2111*f5c631daSSadaf Ebrahimi       VIXL_UNIMPLEMENTED();
2112*f5c631daSSadaf Ebrahimi     }
2113*f5c631daSSadaf Ebrahimi   }
2114*f5c631daSSadaf Ebrahimi 
2115*f5c631daSSadaf Ebrahimi   // Misc instructions.
2116*f5c631daSSadaf Ebrahimi 
2117*f5c631daSSadaf Ebrahimi   // Monitor debug-mode breakpoint.
2118*f5c631daSSadaf Ebrahimi   void brk(int code);
2119*f5c631daSSadaf Ebrahimi 
2120*f5c631daSSadaf Ebrahimi   // Halting debug-mode breakpoint.
2121*f5c631daSSadaf Ebrahimi   void hlt(int code);
2122*f5c631daSSadaf Ebrahimi 
2123*f5c631daSSadaf Ebrahimi   // Generate exception targeting EL1.
2124*f5c631daSSadaf Ebrahimi   void svc(int code);
2125*f5c631daSSadaf Ebrahimi 
2126*f5c631daSSadaf Ebrahimi   // Generate undefined instruction exception.
2127*f5c631daSSadaf Ebrahimi   void udf(int code);
2128*f5c631daSSadaf Ebrahimi 
2129*f5c631daSSadaf Ebrahimi   // Move register to register.
2130*f5c631daSSadaf Ebrahimi   void mov(const Register& rd, const Register& rn);
2131*f5c631daSSadaf Ebrahimi 
2132*f5c631daSSadaf Ebrahimi   // Move inverted operand to register.
2133*f5c631daSSadaf Ebrahimi   void mvn(const Register& rd, const Operand& operand);
2134*f5c631daSSadaf Ebrahimi 
2135*f5c631daSSadaf Ebrahimi   // System instructions.
2136*f5c631daSSadaf Ebrahimi 
2137*f5c631daSSadaf Ebrahimi   // Move to register from system register.
2138*f5c631daSSadaf Ebrahimi   void mrs(const Register& xt, SystemRegister sysreg);
2139*f5c631daSSadaf Ebrahimi 
2140*f5c631daSSadaf Ebrahimi   // Move from register to system register.
2141*f5c631daSSadaf Ebrahimi   void msr(SystemRegister sysreg, const Register& xt);
2142*f5c631daSSadaf Ebrahimi 
2143*f5c631daSSadaf Ebrahimi   // Invert carry flag [Armv8.4].
2144*f5c631daSSadaf Ebrahimi   void cfinv();
2145*f5c631daSSadaf Ebrahimi 
2146*f5c631daSSadaf Ebrahimi   // Convert floating-point condition flags from alternative format to Arm
2147*f5c631daSSadaf Ebrahimi   // format [Armv8.5].
2148*f5c631daSSadaf Ebrahimi   void xaflag();
2149*f5c631daSSadaf Ebrahimi 
2150*f5c631daSSadaf Ebrahimi   // Convert floating-point condition flags from Arm format to alternative
2151*f5c631daSSadaf Ebrahimi   // format [Armv8.5].
2152*f5c631daSSadaf Ebrahimi   void axflag();
2153*f5c631daSSadaf Ebrahimi 
2154*f5c631daSSadaf Ebrahimi   // System instruction.
2155*f5c631daSSadaf Ebrahimi   void sys(int op1, int crn, int crm, int op2, const Register& xt = xzr);
2156*f5c631daSSadaf Ebrahimi 
2157*f5c631daSSadaf Ebrahimi   // System instruction with pre-encoded op (op1:crn:crm:op2).
2158*f5c631daSSadaf Ebrahimi   void sys(int op, const Register& xt = xzr);
2159*f5c631daSSadaf Ebrahimi 
2160*f5c631daSSadaf Ebrahimi   // System data cache operation.
2161*f5c631daSSadaf Ebrahimi   void dc(DataCacheOp op, const Register& rt);
2162*f5c631daSSadaf Ebrahimi 
2163*f5c631daSSadaf Ebrahimi   // System instruction cache operation.
2164*f5c631daSSadaf Ebrahimi   void ic(InstructionCacheOp op, const Register& rt);
2165*f5c631daSSadaf Ebrahimi 
2166*f5c631daSSadaf Ebrahimi   // System hint (named type).
2167*f5c631daSSadaf Ebrahimi   void hint(SystemHint code);
2168*f5c631daSSadaf Ebrahimi 
2169*f5c631daSSadaf Ebrahimi   // System hint (numbered type).
2170*f5c631daSSadaf Ebrahimi   void hint(int imm7);
2171*f5c631daSSadaf Ebrahimi 
2172*f5c631daSSadaf Ebrahimi   // Clear exclusive monitor.
2173*f5c631daSSadaf Ebrahimi   void clrex(int imm4 = 0xf);
2174*f5c631daSSadaf Ebrahimi 
2175*f5c631daSSadaf Ebrahimi   // Data memory barrier.
2176*f5c631daSSadaf Ebrahimi   void dmb(BarrierDomain domain, BarrierType type);
2177*f5c631daSSadaf Ebrahimi 
2178*f5c631daSSadaf Ebrahimi   // Data synchronization barrier.
2179*f5c631daSSadaf Ebrahimi   void dsb(BarrierDomain domain, BarrierType type);
2180*f5c631daSSadaf Ebrahimi 
2181*f5c631daSSadaf Ebrahimi   // Instruction synchronization barrier.
2182*f5c631daSSadaf Ebrahimi   void isb();
2183*f5c631daSSadaf Ebrahimi 
2184*f5c631daSSadaf Ebrahimi   // Error synchronization barrier.
2185*f5c631daSSadaf Ebrahimi   void esb();
2186*f5c631daSSadaf Ebrahimi 
2187*f5c631daSSadaf Ebrahimi   // Conditional speculation dependency barrier.
2188*f5c631daSSadaf Ebrahimi   void csdb();
2189*f5c631daSSadaf Ebrahimi 
2190*f5c631daSSadaf Ebrahimi   // No-op.
nop()2191*f5c631daSSadaf Ebrahimi   void nop() { hint(NOP); }
2192*f5c631daSSadaf Ebrahimi 
2193*f5c631daSSadaf Ebrahimi   // Branch target identification.
2194*f5c631daSSadaf Ebrahimi   void bti(BranchTargetIdentifier id);
2195*f5c631daSSadaf Ebrahimi 
2196*f5c631daSSadaf Ebrahimi   // FP and NEON instructions.
2197*f5c631daSSadaf Ebrahimi 
2198*f5c631daSSadaf Ebrahimi   // Move double precision immediate to FP register.
2199*f5c631daSSadaf Ebrahimi   void fmov(const VRegister& vd, double imm);
2200*f5c631daSSadaf Ebrahimi 
2201*f5c631daSSadaf Ebrahimi   // Move single precision immediate to FP register.
2202*f5c631daSSadaf Ebrahimi   void fmov(const VRegister& vd, float imm);
2203*f5c631daSSadaf Ebrahimi 
2204*f5c631daSSadaf Ebrahimi   // Move half precision immediate to FP register [Armv8.2].
2205*f5c631daSSadaf Ebrahimi   void fmov(const VRegister& vd, Float16 imm);
2206*f5c631daSSadaf Ebrahimi 
2207*f5c631daSSadaf Ebrahimi   // Move FP register to register.
2208*f5c631daSSadaf Ebrahimi   void fmov(const Register& rd, const VRegister& fn);
2209*f5c631daSSadaf Ebrahimi 
2210*f5c631daSSadaf Ebrahimi   // Move register to FP register.
2211*f5c631daSSadaf Ebrahimi   void fmov(const VRegister& vd, const Register& rn);
2212*f5c631daSSadaf Ebrahimi 
2213*f5c631daSSadaf Ebrahimi   // Move FP register to FP register.
2214*f5c631daSSadaf Ebrahimi   void fmov(const VRegister& vd, const VRegister& fn);
2215*f5c631daSSadaf Ebrahimi 
2216*f5c631daSSadaf Ebrahimi   // Move 64-bit register to top half of 128-bit FP register.
2217*f5c631daSSadaf Ebrahimi   void fmov(const VRegister& vd, int index, const Register& rn);
2218*f5c631daSSadaf Ebrahimi 
2219*f5c631daSSadaf Ebrahimi   // Move top half of 128-bit FP register to 64-bit register.
2220*f5c631daSSadaf Ebrahimi   void fmov(const Register& rd, const VRegister& vn, int index);
2221*f5c631daSSadaf Ebrahimi 
2222*f5c631daSSadaf Ebrahimi   // FP add.
2223*f5c631daSSadaf Ebrahimi   void fadd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2224*f5c631daSSadaf Ebrahimi 
2225*f5c631daSSadaf Ebrahimi   // FP subtract.
2226*f5c631daSSadaf Ebrahimi   void fsub(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2227*f5c631daSSadaf Ebrahimi 
2228*f5c631daSSadaf Ebrahimi   // FP multiply.
2229*f5c631daSSadaf Ebrahimi   void fmul(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2230*f5c631daSSadaf Ebrahimi 
2231*f5c631daSSadaf Ebrahimi   // FP fused multiply-add.
2232*f5c631daSSadaf Ebrahimi   void fmadd(const VRegister& vd,
2233*f5c631daSSadaf Ebrahimi              const VRegister& vn,
2234*f5c631daSSadaf Ebrahimi              const VRegister& vm,
2235*f5c631daSSadaf Ebrahimi              const VRegister& va);
2236*f5c631daSSadaf Ebrahimi 
2237*f5c631daSSadaf Ebrahimi   // FP fused multiply-subtract.
2238*f5c631daSSadaf Ebrahimi   void fmsub(const VRegister& vd,
2239*f5c631daSSadaf Ebrahimi              const VRegister& vn,
2240*f5c631daSSadaf Ebrahimi              const VRegister& vm,
2241*f5c631daSSadaf Ebrahimi              const VRegister& va);
2242*f5c631daSSadaf Ebrahimi 
2243*f5c631daSSadaf Ebrahimi   // FP fused multiply-add and negate.
2244*f5c631daSSadaf Ebrahimi   void fnmadd(const VRegister& vd,
2245*f5c631daSSadaf Ebrahimi               const VRegister& vn,
2246*f5c631daSSadaf Ebrahimi               const VRegister& vm,
2247*f5c631daSSadaf Ebrahimi               const VRegister& va);
2248*f5c631daSSadaf Ebrahimi 
2249*f5c631daSSadaf Ebrahimi   // FP fused multiply-subtract and negate.
2250*f5c631daSSadaf Ebrahimi   void fnmsub(const VRegister& vd,
2251*f5c631daSSadaf Ebrahimi               const VRegister& vn,
2252*f5c631daSSadaf Ebrahimi               const VRegister& vm,
2253*f5c631daSSadaf Ebrahimi               const VRegister& va);
2254*f5c631daSSadaf Ebrahimi 
2255*f5c631daSSadaf Ebrahimi   // FP multiply-negate scalar.
2256*f5c631daSSadaf Ebrahimi   void fnmul(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2257*f5c631daSSadaf Ebrahimi 
2258*f5c631daSSadaf Ebrahimi   // FP reciprocal exponent scalar.
2259*f5c631daSSadaf Ebrahimi   void frecpx(const VRegister& vd, const VRegister& vn);
2260*f5c631daSSadaf Ebrahimi 
2261*f5c631daSSadaf Ebrahimi   // FP divide.
2262*f5c631daSSadaf Ebrahimi   void fdiv(const VRegister& vd, const VRegister& fn, const VRegister& vm);
2263*f5c631daSSadaf Ebrahimi 
2264*f5c631daSSadaf Ebrahimi   // FP maximum.
2265*f5c631daSSadaf Ebrahimi   void fmax(const VRegister& vd, const VRegister& fn, const VRegister& vm);
2266*f5c631daSSadaf Ebrahimi 
2267*f5c631daSSadaf Ebrahimi   // FP minimum.
2268*f5c631daSSadaf Ebrahimi   void fmin(const VRegister& vd, const VRegister& fn, const VRegister& vm);
2269*f5c631daSSadaf Ebrahimi 
2270*f5c631daSSadaf Ebrahimi   // FP maximum number.
2271*f5c631daSSadaf Ebrahimi   void fmaxnm(const VRegister& vd, const VRegister& fn, const VRegister& vm);
2272*f5c631daSSadaf Ebrahimi 
2273*f5c631daSSadaf Ebrahimi   // FP minimum number.
2274*f5c631daSSadaf Ebrahimi   void fminnm(const VRegister& vd, const VRegister& fn, const VRegister& vm);
2275*f5c631daSSadaf Ebrahimi 
2276*f5c631daSSadaf Ebrahimi   // FP absolute.
2277*f5c631daSSadaf Ebrahimi   void fabs(const VRegister& vd, const VRegister& vn);
2278*f5c631daSSadaf Ebrahimi 
2279*f5c631daSSadaf Ebrahimi   // FP negate.
2280*f5c631daSSadaf Ebrahimi   void fneg(const VRegister& vd, const VRegister& vn);
2281*f5c631daSSadaf Ebrahimi 
2282*f5c631daSSadaf Ebrahimi   // FP square root.
2283*f5c631daSSadaf Ebrahimi   void fsqrt(const VRegister& vd, const VRegister& vn);
2284*f5c631daSSadaf Ebrahimi 
2285*f5c631daSSadaf Ebrahimi   // FP round to integer, nearest with ties to away.
2286*f5c631daSSadaf Ebrahimi   void frinta(const VRegister& vd, const VRegister& vn);
2287*f5c631daSSadaf Ebrahimi 
2288*f5c631daSSadaf Ebrahimi   // FP round to integer, implicit rounding.
2289*f5c631daSSadaf Ebrahimi   void frinti(const VRegister& vd, const VRegister& vn);
2290*f5c631daSSadaf Ebrahimi 
2291*f5c631daSSadaf Ebrahimi   // FP round to integer, toward minus infinity.
2292*f5c631daSSadaf Ebrahimi   void frintm(const VRegister& vd, const VRegister& vn);
2293*f5c631daSSadaf Ebrahimi 
2294*f5c631daSSadaf Ebrahimi   // FP round to integer, nearest with ties to even.
2295*f5c631daSSadaf Ebrahimi   void frintn(const VRegister& vd, const VRegister& vn);
2296*f5c631daSSadaf Ebrahimi 
2297*f5c631daSSadaf Ebrahimi   // FP round to integer, toward plus infinity.
2298*f5c631daSSadaf Ebrahimi   void frintp(const VRegister& vd, const VRegister& vn);
2299*f5c631daSSadaf Ebrahimi 
2300*f5c631daSSadaf Ebrahimi   // FP round to integer, exact, implicit rounding.
2301*f5c631daSSadaf Ebrahimi   void frintx(const VRegister& vd, const VRegister& vn);
2302*f5c631daSSadaf Ebrahimi 
2303*f5c631daSSadaf Ebrahimi   // FP round to integer, towards zero.
2304*f5c631daSSadaf Ebrahimi   void frintz(const VRegister& vd, const VRegister& vn);
2305*f5c631daSSadaf Ebrahimi 
2306*f5c631daSSadaf Ebrahimi   // FP round to 32-bit integer, exact, implicit rounding [Armv8.5].
2307*f5c631daSSadaf Ebrahimi   void frint32x(const VRegister& vd, const VRegister& vn);
2308*f5c631daSSadaf Ebrahimi 
2309*f5c631daSSadaf Ebrahimi   // FP round to 32-bit integer, towards zero [Armv8.5].
2310*f5c631daSSadaf Ebrahimi   void frint32z(const VRegister& vd, const VRegister& vn);
2311*f5c631daSSadaf Ebrahimi 
2312*f5c631daSSadaf Ebrahimi   // FP round to 64-bit integer, exact, implicit rounding [Armv8.5].
2313*f5c631daSSadaf Ebrahimi   void frint64x(const VRegister& vd, const VRegister& vn);
2314*f5c631daSSadaf Ebrahimi 
2315*f5c631daSSadaf Ebrahimi   // FP round to 64-bit integer, towards zero [Armv8.5].
2316*f5c631daSSadaf Ebrahimi   void frint64z(const VRegister& vd, const VRegister& vn);
2317*f5c631daSSadaf Ebrahimi 
2318*f5c631daSSadaf Ebrahimi   void FPCompareMacro(const VRegister& vn, double value, FPTrapFlags trap);
2319*f5c631daSSadaf Ebrahimi 
2320*f5c631daSSadaf Ebrahimi   void FPCompareMacro(const VRegister& vn,
2321*f5c631daSSadaf Ebrahimi                       const VRegister& vm,
2322*f5c631daSSadaf Ebrahimi                       FPTrapFlags trap);
2323*f5c631daSSadaf Ebrahimi 
2324*f5c631daSSadaf Ebrahimi   // FP compare registers.
2325*f5c631daSSadaf Ebrahimi   void fcmp(const VRegister& vn, const VRegister& vm);
2326*f5c631daSSadaf Ebrahimi 
2327*f5c631daSSadaf Ebrahimi   // FP compare immediate.
2328*f5c631daSSadaf Ebrahimi   void fcmp(const VRegister& vn, double value);
2329*f5c631daSSadaf Ebrahimi 
2330*f5c631daSSadaf Ebrahimi   void FPCCompareMacro(const VRegister& vn,
2331*f5c631daSSadaf Ebrahimi                        const VRegister& vm,
2332*f5c631daSSadaf Ebrahimi                        StatusFlags nzcv,
2333*f5c631daSSadaf Ebrahimi                        Condition cond,
2334*f5c631daSSadaf Ebrahimi                        FPTrapFlags trap);
2335*f5c631daSSadaf Ebrahimi 
2336*f5c631daSSadaf Ebrahimi   // FP conditional compare.
2337*f5c631daSSadaf Ebrahimi   void fccmp(const VRegister& vn,
2338*f5c631daSSadaf Ebrahimi              const VRegister& vm,
2339*f5c631daSSadaf Ebrahimi              StatusFlags nzcv,
2340*f5c631daSSadaf Ebrahimi              Condition cond);
2341*f5c631daSSadaf Ebrahimi 
2342*f5c631daSSadaf Ebrahimi   // FP signaling compare registers.
2343*f5c631daSSadaf Ebrahimi   void fcmpe(const VRegister& vn, const VRegister& vm);
2344*f5c631daSSadaf Ebrahimi 
2345*f5c631daSSadaf Ebrahimi   // FP signaling compare immediate.
2346*f5c631daSSadaf Ebrahimi   void fcmpe(const VRegister& vn, double value);
2347*f5c631daSSadaf Ebrahimi 
2348*f5c631daSSadaf Ebrahimi   // FP conditional signaling compare.
2349*f5c631daSSadaf Ebrahimi   void fccmpe(const VRegister& vn,
2350*f5c631daSSadaf Ebrahimi               const VRegister& vm,
2351*f5c631daSSadaf Ebrahimi               StatusFlags nzcv,
2352*f5c631daSSadaf Ebrahimi               Condition cond);
2353*f5c631daSSadaf Ebrahimi 
2354*f5c631daSSadaf Ebrahimi   // FP conditional select.
2355*f5c631daSSadaf Ebrahimi   void fcsel(const VRegister& vd,
2356*f5c631daSSadaf Ebrahimi              const VRegister& vn,
2357*f5c631daSSadaf Ebrahimi              const VRegister& vm,
2358*f5c631daSSadaf Ebrahimi              Condition cond);
2359*f5c631daSSadaf Ebrahimi 
2360*f5c631daSSadaf Ebrahimi   // Common FP Convert functions.
2361*f5c631daSSadaf Ebrahimi   void NEONFPConvertToInt(const Register& rd, const VRegister& vn, Instr op);
2362*f5c631daSSadaf Ebrahimi   void NEONFPConvertToInt(const VRegister& vd, const VRegister& vn, Instr op);
2363*f5c631daSSadaf Ebrahimi   void NEONFP16ConvertToInt(const VRegister& vd, const VRegister& vn, Instr op);
2364*f5c631daSSadaf Ebrahimi 
2365*f5c631daSSadaf Ebrahimi   // FP convert between precisions.
2366*f5c631daSSadaf Ebrahimi   void fcvt(const VRegister& vd, const VRegister& vn);
2367*f5c631daSSadaf Ebrahimi 
2368*f5c631daSSadaf Ebrahimi   // FP convert to higher precision.
2369*f5c631daSSadaf Ebrahimi   void fcvtl(const VRegister& vd, const VRegister& vn);
2370*f5c631daSSadaf Ebrahimi 
2371*f5c631daSSadaf Ebrahimi   // FP convert to higher precision (second part).
2372*f5c631daSSadaf Ebrahimi   void fcvtl2(const VRegister& vd, const VRegister& vn);
2373*f5c631daSSadaf Ebrahimi 
2374*f5c631daSSadaf Ebrahimi   // FP convert to lower precision.
2375*f5c631daSSadaf Ebrahimi   void fcvtn(const VRegister& vd, const VRegister& vn);
2376*f5c631daSSadaf Ebrahimi 
2377*f5c631daSSadaf Ebrahimi   // FP convert to lower prevision (second part).
2378*f5c631daSSadaf Ebrahimi   void fcvtn2(const VRegister& vd, const VRegister& vn);
2379*f5c631daSSadaf Ebrahimi 
2380*f5c631daSSadaf Ebrahimi   // FP convert to lower precision, rounding to odd.
2381*f5c631daSSadaf Ebrahimi   void fcvtxn(const VRegister& vd, const VRegister& vn);
2382*f5c631daSSadaf Ebrahimi 
2383*f5c631daSSadaf Ebrahimi   // FP convert to lower precision, rounding to odd (second part).
2384*f5c631daSSadaf Ebrahimi   void fcvtxn2(const VRegister& vd, const VRegister& vn);
2385*f5c631daSSadaf Ebrahimi 
2386*f5c631daSSadaf Ebrahimi   // FP convert to signed integer, nearest with ties to away.
2387*f5c631daSSadaf Ebrahimi   void fcvtas(const Register& rd, const VRegister& vn);
2388*f5c631daSSadaf Ebrahimi 
2389*f5c631daSSadaf Ebrahimi   // FP convert to unsigned integer, nearest with ties to away.
2390*f5c631daSSadaf Ebrahimi   void fcvtau(const Register& rd, const VRegister& vn);
2391*f5c631daSSadaf Ebrahimi 
2392*f5c631daSSadaf Ebrahimi   // FP convert to signed integer, nearest with ties to away.
2393*f5c631daSSadaf Ebrahimi   void fcvtas(const VRegister& vd, const VRegister& vn);
2394*f5c631daSSadaf Ebrahimi 
2395*f5c631daSSadaf Ebrahimi   // FP convert to unsigned integer, nearest with ties to away.
2396*f5c631daSSadaf Ebrahimi   void fcvtau(const VRegister& vd, const VRegister& vn);
2397*f5c631daSSadaf Ebrahimi 
2398*f5c631daSSadaf Ebrahimi   // FP convert to signed integer, round towards -infinity.
2399*f5c631daSSadaf Ebrahimi   void fcvtms(const Register& rd, const VRegister& vn);
2400*f5c631daSSadaf Ebrahimi 
2401*f5c631daSSadaf Ebrahimi   // FP convert to unsigned integer, round towards -infinity.
2402*f5c631daSSadaf Ebrahimi   void fcvtmu(const Register& rd, const VRegister& vn);
2403*f5c631daSSadaf Ebrahimi 
2404*f5c631daSSadaf Ebrahimi   // FP convert to signed integer, round towards -infinity.
2405*f5c631daSSadaf Ebrahimi   void fcvtms(const VRegister& vd, const VRegister& vn);
2406*f5c631daSSadaf Ebrahimi 
2407*f5c631daSSadaf Ebrahimi   // FP convert to unsigned integer, round towards -infinity.
2408*f5c631daSSadaf Ebrahimi   void fcvtmu(const VRegister& vd, const VRegister& vn);
2409*f5c631daSSadaf Ebrahimi 
2410*f5c631daSSadaf Ebrahimi   // FP convert to signed integer, nearest with ties to even.
2411*f5c631daSSadaf Ebrahimi   void fcvtns(const Register& rd, const VRegister& vn);
2412*f5c631daSSadaf Ebrahimi 
2413*f5c631daSSadaf Ebrahimi   // FP JavaScript convert to signed integer, rounding toward zero [Armv8.3].
2414*f5c631daSSadaf Ebrahimi   void fjcvtzs(const Register& rd, const VRegister& vn);
2415*f5c631daSSadaf Ebrahimi 
2416*f5c631daSSadaf Ebrahimi   // FP convert to unsigned integer, nearest with ties to even.
2417*f5c631daSSadaf Ebrahimi   void fcvtnu(const Register& rd, const VRegister& vn);
2418*f5c631daSSadaf Ebrahimi 
2419*f5c631daSSadaf Ebrahimi   // FP convert to signed integer, nearest with ties to even.
2420*f5c631daSSadaf Ebrahimi   void fcvtns(const VRegister& rd, const VRegister& vn);
2421*f5c631daSSadaf Ebrahimi 
2422*f5c631daSSadaf Ebrahimi   // FP convert to unsigned integer, nearest with ties to even.
2423*f5c631daSSadaf Ebrahimi   void fcvtnu(const VRegister& rd, const VRegister& vn);
2424*f5c631daSSadaf Ebrahimi 
2425*f5c631daSSadaf Ebrahimi   // FP convert to signed integer or fixed-point, round towards zero.
2426*f5c631daSSadaf Ebrahimi   void fcvtzs(const Register& rd, const VRegister& vn, int fbits = 0);
2427*f5c631daSSadaf Ebrahimi 
2428*f5c631daSSadaf Ebrahimi   // FP convert to unsigned integer or fixed-point, round towards zero.
2429*f5c631daSSadaf Ebrahimi   void fcvtzu(const Register& rd, const VRegister& vn, int fbits = 0);
2430*f5c631daSSadaf Ebrahimi 
2431*f5c631daSSadaf Ebrahimi   // FP convert to signed integer or fixed-point, round towards zero.
2432*f5c631daSSadaf Ebrahimi   void fcvtzs(const VRegister& vd, const VRegister& vn, int fbits = 0);
2433*f5c631daSSadaf Ebrahimi 
2434*f5c631daSSadaf Ebrahimi   // FP convert to unsigned integer or fixed-point, round towards zero.
2435*f5c631daSSadaf Ebrahimi   void fcvtzu(const VRegister& vd, const VRegister& vn, int fbits = 0);
2436*f5c631daSSadaf Ebrahimi 
2437*f5c631daSSadaf Ebrahimi   // FP convert to signed integer, round towards +infinity.
2438*f5c631daSSadaf Ebrahimi   void fcvtps(const Register& rd, const VRegister& vn);
2439*f5c631daSSadaf Ebrahimi 
2440*f5c631daSSadaf Ebrahimi   // FP convert to unsigned integer, round towards +infinity.
2441*f5c631daSSadaf Ebrahimi   void fcvtpu(const Register& rd, const VRegister& vn);
2442*f5c631daSSadaf Ebrahimi 
2443*f5c631daSSadaf Ebrahimi   // FP convert to signed integer, round towards +infinity.
2444*f5c631daSSadaf Ebrahimi   void fcvtps(const VRegister& vd, const VRegister& vn);
2445*f5c631daSSadaf Ebrahimi 
2446*f5c631daSSadaf Ebrahimi   // FP convert to unsigned integer, round towards +infinity.
2447*f5c631daSSadaf Ebrahimi   void fcvtpu(const VRegister& vd, const VRegister& vn);
2448*f5c631daSSadaf Ebrahimi 
2449*f5c631daSSadaf Ebrahimi   // Convert signed integer or fixed point to FP.
2450*f5c631daSSadaf Ebrahimi   void scvtf(const VRegister& fd, const Register& rn, int fbits = 0);
2451*f5c631daSSadaf Ebrahimi 
2452*f5c631daSSadaf Ebrahimi   // Convert unsigned integer or fixed point to FP.
2453*f5c631daSSadaf Ebrahimi   void ucvtf(const VRegister& fd, const Register& rn, int fbits = 0);
2454*f5c631daSSadaf Ebrahimi 
2455*f5c631daSSadaf Ebrahimi   // Convert signed integer or fixed-point to FP.
2456*f5c631daSSadaf Ebrahimi   void scvtf(const VRegister& fd, const VRegister& vn, int fbits = 0);
2457*f5c631daSSadaf Ebrahimi 
2458*f5c631daSSadaf Ebrahimi   // Convert unsigned integer or fixed-point to FP.
2459*f5c631daSSadaf Ebrahimi   void ucvtf(const VRegister& fd, const VRegister& vn, int fbits = 0);
2460*f5c631daSSadaf Ebrahimi 
2461*f5c631daSSadaf Ebrahimi   // Unsigned absolute difference.
2462*f5c631daSSadaf Ebrahimi   void uabd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2463*f5c631daSSadaf Ebrahimi 
2464*f5c631daSSadaf Ebrahimi   // Signed absolute difference.
2465*f5c631daSSadaf Ebrahimi   void sabd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2466*f5c631daSSadaf Ebrahimi 
2467*f5c631daSSadaf Ebrahimi   // Unsigned absolute difference and accumulate.
2468*f5c631daSSadaf Ebrahimi   void uaba(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2469*f5c631daSSadaf Ebrahimi 
2470*f5c631daSSadaf Ebrahimi   // Signed absolute difference and accumulate.
2471*f5c631daSSadaf Ebrahimi   void saba(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2472*f5c631daSSadaf Ebrahimi 
2473*f5c631daSSadaf Ebrahimi   // Add.
2474*f5c631daSSadaf Ebrahimi   void add(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2475*f5c631daSSadaf Ebrahimi 
2476*f5c631daSSadaf Ebrahimi   // Subtract.
2477*f5c631daSSadaf Ebrahimi   void sub(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2478*f5c631daSSadaf Ebrahimi 
2479*f5c631daSSadaf Ebrahimi   // Unsigned halving add.
2480*f5c631daSSadaf Ebrahimi   void uhadd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2481*f5c631daSSadaf Ebrahimi 
2482*f5c631daSSadaf Ebrahimi   // Signed halving add.
2483*f5c631daSSadaf Ebrahimi   void shadd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2484*f5c631daSSadaf Ebrahimi 
2485*f5c631daSSadaf Ebrahimi   // Unsigned rounding halving add.
2486*f5c631daSSadaf Ebrahimi   void urhadd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2487*f5c631daSSadaf Ebrahimi 
2488*f5c631daSSadaf Ebrahimi   // Signed rounding halving add.
2489*f5c631daSSadaf Ebrahimi   void srhadd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2490*f5c631daSSadaf Ebrahimi 
2491*f5c631daSSadaf Ebrahimi   // Unsigned halving sub.
2492*f5c631daSSadaf Ebrahimi   void uhsub(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2493*f5c631daSSadaf Ebrahimi 
2494*f5c631daSSadaf Ebrahimi   // Signed halving sub.
2495*f5c631daSSadaf Ebrahimi   void shsub(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2496*f5c631daSSadaf Ebrahimi 
2497*f5c631daSSadaf Ebrahimi   // Unsigned saturating add.
2498*f5c631daSSadaf Ebrahimi   void uqadd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2499*f5c631daSSadaf Ebrahimi 
2500*f5c631daSSadaf Ebrahimi   // Signed saturating add.
2501*f5c631daSSadaf Ebrahimi   void sqadd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2502*f5c631daSSadaf Ebrahimi 
2503*f5c631daSSadaf Ebrahimi   // Unsigned saturating subtract.
2504*f5c631daSSadaf Ebrahimi   void uqsub(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2505*f5c631daSSadaf Ebrahimi 
2506*f5c631daSSadaf Ebrahimi   // Signed saturating subtract.
2507*f5c631daSSadaf Ebrahimi   void sqsub(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2508*f5c631daSSadaf Ebrahimi 
2509*f5c631daSSadaf Ebrahimi   // Add pairwise.
2510*f5c631daSSadaf Ebrahimi   void addp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2511*f5c631daSSadaf Ebrahimi 
2512*f5c631daSSadaf Ebrahimi   // Add pair of elements scalar.
2513*f5c631daSSadaf Ebrahimi   void addp(const VRegister& vd, const VRegister& vn);
2514*f5c631daSSadaf Ebrahimi 
2515*f5c631daSSadaf Ebrahimi   // Multiply-add to accumulator.
2516*f5c631daSSadaf Ebrahimi   void mla(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2517*f5c631daSSadaf Ebrahimi 
2518*f5c631daSSadaf Ebrahimi   // Multiply-subtract to accumulator.
2519*f5c631daSSadaf Ebrahimi   void mls(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2520*f5c631daSSadaf Ebrahimi 
2521*f5c631daSSadaf Ebrahimi   // Multiply.
2522*f5c631daSSadaf Ebrahimi   void mul(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2523*f5c631daSSadaf Ebrahimi 
2524*f5c631daSSadaf Ebrahimi   // Multiply by scalar element.
2525*f5c631daSSadaf Ebrahimi   void mul(const VRegister& vd,
2526*f5c631daSSadaf Ebrahimi            const VRegister& vn,
2527*f5c631daSSadaf Ebrahimi            const VRegister& vm,
2528*f5c631daSSadaf Ebrahimi            int vm_index);
2529*f5c631daSSadaf Ebrahimi 
2530*f5c631daSSadaf Ebrahimi   // Multiply-add by scalar element.
2531*f5c631daSSadaf Ebrahimi   void mla(const VRegister& vd,
2532*f5c631daSSadaf Ebrahimi            const VRegister& vn,
2533*f5c631daSSadaf Ebrahimi            const VRegister& vm,
2534*f5c631daSSadaf Ebrahimi            int vm_index);
2535*f5c631daSSadaf Ebrahimi 
2536*f5c631daSSadaf Ebrahimi   // Multiply-subtract by scalar element.
2537*f5c631daSSadaf Ebrahimi   void mls(const VRegister& vd,
2538*f5c631daSSadaf Ebrahimi            const VRegister& vn,
2539*f5c631daSSadaf Ebrahimi            const VRegister& vm,
2540*f5c631daSSadaf Ebrahimi            int vm_index);
2541*f5c631daSSadaf Ebrahimi 
2542*f5c631daSSadaf Ebrahimi   // Signed long multiply-add by scalar element.
2543*f5c631daSSadaf Ebrahimi   void smlal(const VRegister& vd,
2544*f5c631daSSadaf Ebrahimi              const VRegister& vn,
2545*f5c631daSSadaf Ebrahimi              const VRegister& vm,
2546*f5c631daSSadaf Ebrahimi              int vm_index);
2547*f5c631daSSadaf Ebrahimi 
2548*f5c631daSSadaf Ebrahimi   // Signed long multiply-add by scalar element (second part).
2549*f5c631daSSadaf Ebrahimi   void smlal2(const VRegister& vd,
2550*f5c631daSSadaf Ebrahimi               const VRegister& vn,
2551*f5c631daSSadaf Ebrahimi               const VRegister& vm,
2552*f5c631daSSadaf Ebrahimi               int vm_index);
2553*f5c631daSSadaf Ebrahimi 
2554*f5c631daSSadaf Ebrahimi   // Unsigned long multiply-add by scalar element.
2555*f5c631daSSadaf Ebrahimi   void umlal(const VRegister& vd,
2556*f5c631daSSadaf Ebrahimi              const VRegister& vn,
2557*f5c631daSSadaf Ebrahimi              const VRegister& vm,
2558*f5c631daSSadaf Ebrahimi              int vm_index);
2559*f5c631daSSadaf Ebrahimi 
2560*f5c631daSSadaf Ebrahimi   // Unsigned long multiply-add by scalar element (second part).
2561*f5c631daSSadaf Ebrahimi   void umlal2(const VRegister& vd,
2562*f5c631daSSadaf Ebrahimi               const VRegister& vn,
2563*f5c631daSSadaf Ebrahimi               const VRegister& vm,
2564*f5c631daSSadaf Ebrahimi               int vm_index);
2565*f5c631daSSadaf Ebrahimi 
2566*f5c631daSSadaf Ebrahimi   // Signed long multiply-sub by scalar element.
2567*f5c631daSSadaf Ebrahimi   void smlsl(const VRegister& vd,
2568*f5c631daSSadaf Ebrahimi              const VRegister& vn,
2569*f5c631daSSadaf Ebrahimi              const VRegister& vm,
2570*f5c631daSSadaf Ebrahimi              int vm_index);
2571*f5c631daSSadaf Ebrahimi 
2572*f5c631daSSadaf Ebrahimi   // Signed long multiply-sub by scalar element (second part).
2573*f5c631daSSadaf Ebrahimi   void smlsl2(const VRegister& vd,
2574*f5c631daSSadaf Ebrahimi               const VRegister& vn,
2575*f5c631daSSadaf Ebrahimi               const VRegister& vm,
2576*f5c631daSSadaf Ebrahimi               int vm_index);
2577*f5c631daSSadaf Ebrahimi 
2578*f5c631daSSadaf Ebrahimi   // Unsigned long multiply-sub by scalar element.
2579*f5c631daSSadaf Ebrahimi   void umlsl(const VRegister& vd,
2580*f5c631daSSadaf Ebrahimi              const VRegister& vn,
2581*f5c631daSSadaf Ebrahimi              const VRegister& vm,
2582*f5c631daSSadaf Ebrahimi              int vm_index);
2583*f5c631daSSadaf Ebrahimi 
2584*f5c631daSSadaf Ebrahimi   // Unsigned long multiply-sub by scalar element (second part).
2585*f5c631daSSadaf Ebrahimi   void umlsl2(const VRegister& vd,
2586*f5c631daSSadaf Ebrahimi               const VRegister& vn,
2587*f5c631daSSadaf Ebrahimi               const VRegister& vm,
2588*f5c631daSSadaf Ebrahimi               int vm_index);
2589*f5c631daSSadaf Ebrahimi 
2590*f5c631daSSadaf Ebrahimi   // Signed long multiply by scalar element.
2591*f5c631daSSadaf Ebrahimi   void smull(const VRegister& vd,
2592*f5c631daSSadaf Ebrahimi              const VRegister& vn,
2593*f5c631daSSadaf Ebrahimi              const VRegister& vm,
2594*f5c631daSSadaf Ebrahimi              int vm_index);
2595*f5c631daSSadaf Ebrahimi 
2596*f5c631daSSadaf Ebrahimi   // Signed long multiply by scalar element (second part).
2597*f5c631daSSadaf Ebrahimi   void smull2(const VRegister& vd,
2598*f5c631daSSadaf Ebrahimi               const VRegister& vn,
2599*f5c631daSSadaf Ebrahimi               const VRegister& vm,
2600*f5c631daSSadaf Ebrahimi               int vm_index);
2601*f5c631daSSadaf Ebrahimi 
2602*f5c631daSSadaf Ebrahimi   // Unsigned long multiply by scalar element.
2603*f5c631daSSadaf Ebrahimi   void umull(const VRegister& vd,
2604*f5c631daSSadaf Ebrahimi              const VRegister& vn,
2605*f5c631daSSadaf Ebrahimi              const VRegister& vm,
2606*f5c631daSSadaf Ebrahimi              int vm_index);
2607*f5c631daSSadaf Ebrahimi 
2608*f5c631daSSadaf Ebrahimi   // Unsigned long multiply by scalar element (second part).
2609*f5c631daSSadaf Ebrahimi   void umull2(const VRegister& vd,
2610*f5c631daSSadaf Ebrahimi               const VRegister& vn,
2611*f5c631daSSadaf Ebrahimi               const VRegister& vm,
2612*f5c631daSSadaf Ebrahimi               int vm_index);
2613*f5c631daSSadaf Ebrahimi 
2614*f5c631daSSadaf Ebrahimi   // Signed saturating double long multiply by element.
2615*f5c631daSSadaf Ebrahimi   void sqdmull(const VRegister& vd,
2616*f5c631daSSadaf Ebrahimi                const VRegister& vn,
2617*f5c631daSSadaf Ebrahimi                const VRegister& vm,
2618*f5c631daSSadaf Ebrahimi                int vm_index);
2619*f5c631daSSadaf Ebrahimi 
2620*f5c631daSSadaf Ebrahimi   // Signed saturating double long multiply by element (second part).
2621*f5c631daSSadaf Ebrahimi   void sqdmull2(const VRegister& vd,
2622*f5c631daSSadaf Ebrahimi                 const VRegister& vn,
2623*f5c631daSSadaf Ebrahimi                 const VRegister& vm,
2624*f5c631daSSadaf Ebrahimi                 int vm_index);
2625*f5c631daSSadaf Ebrahimi 
2626*f5c631daSSadaf Ebrahimi   // Signed saturating doubling long multiply-add by element.
2627*f5c631daSSadaf Ebrahimi   void sqdmlal(const VRegister& vd,
2628*f5c631daSSadaf Ebrahimi                const VRegister& vn,
2629*f5c631daSSadaf Ebrahimi                const VRegister& vm,
2630*f5c631daSSadaf Ebrahimi                int vm_index);
2631*f5c631daSSadaf Ebrahimi 
2632*f5c631daSSadaf Ebrahimi   // Signed saturating doubling long multiply-add by element (second part).
2633*f5c631daSSadaf Ebrahimi   void sqdmlal2(const VRegister& vd,
2634*f5c631daSSadaf Ebrahimi                 const VRegister& vn,
2635*f5c631daSSadaf Ebrahimi                 const VRegister& vm,
2636*f5c631daSSadaf Ebrahimi                 int vm_index);
2637*f5c631daSSadaf Ebrahimi 
2638*f5c631daSSadaf Ebrahimi   // Signed saturating doubling long multiply-sub by element.
2639*f5c631daSSadaf Ebrahimi   void sqdmlsl(const VRegister& vd,
2640*f5c631daSSadaf Ebrahimi                const VRegister& vn,
2641*f5c631daSSadaf Ebrahimi                const VRegister& vm,
2642*f5c631daSSadaf Ebrahimi                int vm_index);
2643*f5c631daSSadaf Ebrahimi 
2644*f5c631daSSadaf Ebrahimi   // Signed saturating doubling long multiply-sub by element (second part).
2645*f5c631daSSadaf Ebrahimi   void sqdmlsl2(const VRegister& vd,
2646*f5c631daSSadaf Ebrahimi                 const VRegister& vn,
2647*f5c631daSSadaf Ebrahimi                 const VRegister& vm,
2648*f5c631daSSadaf Ebrahimi                 int vm_index);
2649*f5c631daSSadaf Ebrahimi 
2650*f5c631daSSadaf Ebrahimi   // Compare equal.
2651*f5c631daSSadaf Ebrahimi   void cmeq(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2652*f5c631daSSadaf Ebrahimi 
2653*f5c631daSSadaf Ebrahimi   // Compare signed greater than or equal.
2654*f5c631daSSadaf Ebrahimi   void cmge(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2655*f5c631daSSadaf Ebrahimi 
2656*f5c631daSSadaf Ebrahimi   // Compare signed greater than.
2657*f5c631daSSadaf Ebrahimi   void cmgt(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2658*f5c631daSSadaf Ebrahimi 
2659*f5c631daSSadaf Ebrahimi   // Compare unsigned higher.
2660*f5c631daSSadaf Ebrahimi   void cmhi(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2661*f5c631daSSadaf Ebrahimi 
2662*f5c631daSSadaf Ebrahimi   // Compare unsigned higher or same.
2663*f5c631daSSadaf Ebrahimi   void cmhs(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2664*f5c631daSSadaf Ebrahimi 
2665*f5c631daSSadaf Ebrahimi   // Compare bitwise test bits nonzero.
2666*f5c631daSSadaf Ebrahimi   void cmtst(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2667*f5c631daSSadaf Ebrahimi 
2668*f5c631daSSadaf Ebrahimi   // Compare bitwise to zero.
2669*f5c631daSSadaf Ebrahimi   void cmeq(const VRegister& vd, const VRegister& vn, int value);
2670*f5c631daSSadaf Ebrahimi 
2671*f5c631daSSadaf Ebrahimi   // Compare signed greater than or equal to zero.
2672*f5c631daSSadaf Ebrahimi   void cmge(const VRegister& vd, const VRegister& vn, int value);
2673*f5c631daSSadaf Ebrahimi 
2674*f5c631daSSadaf Ebrahimi   // Compare signed greater than zero.
2675*f5c631daSSadaf Ebrahimi   void cmgt(const VRegister& vd, const VRegister& vn, int value);
2676*f5c631daSSadaf Ebrahimi 
2677*f5c631daSSadaf Ebrahimi   // Compare signed less than or equal to zero.
2678*f5c631daSSadaf Ebrahimi   void cmle(const VRegister& vd, const VRegister& vn, int value);
2679*f5c631daSSadaf Ebrahimi 
2680*f5c631daSSadaf Ebrahimi   // Compare signed less than zero.
2681*f5c631daSSadaf Ebrahimi   void cmlt(const VRegister& vd, const VRegister& vn, int value);
2682*f5c631daSSadaf Ebrahimi 
2683*f5c631daSSadaf Ebrahimi   // Signed shift left by register.
2684*f5c631daSSadaf Ebrahimi   void sshl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2685*f5c631daSSadaf Ebrahimi 
2686*f5c631daSSadaf Ebrahimi   // Unsigned shift left by register.
2687*f5c631daSSadaf Ebrahimi   void ushl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2688*f5c631daSSadaf Ebrahimi 
2689*f5c631daSSadaf Ebrahimi   // Signed saturating shift left by register.
2690*f5c631daSSadaf Ebrahimi   void sqshl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2691*f5c631daSSadaf Ebrahimi 
2692*f5c631daSSadaf Ebrahimi   // Unsigned saturating shift left by register.
2693*f5c631daSSadaf Ebrahimi   void uqshl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2694*f5c631daSSadaf Ebrahimi 
2695*f5c631daSSadaf Ebrahimi   // Signed rounding shift left by register.
2696*f5c631daSSadaf Ebrahimi   void srshl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2697*f5c631daSSadaf Ebrahimi 
2698*f5c631daSSadaf Ebrahimi   // Unsigned rounding shift left by register.
2699*f5c631daSSadaf Ebrahimi   void urshl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2700*f5c631daSSadaf Ebrahimi 
2701*f5c631daSSadaf Ebrahimi   // Signed saturating rounding shift left by register.
2702*f5c631daSSadaf Ebrahimi   void sqrshl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2703*f5c631daSSadaf Ebrahimi 
2704*f5c631daSSadaf Ebrahimi   // Unsigned saturating rounding shift left by register.
2705*f5c631daSSadaf Ebrahimi   void uqrshl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2706*f5c631daSSadaf Ebrahimi 
2707*f5c631daSSadaf Ebrahimi   // Bitwise and.
2708*f5c631daSSadaf Ebrahimi   void and_(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2709*f5c631daSSadaf Ebrahimi 
2710*f5c631daSSadaf Ebrahimi   // Bitwise or.
2711*f5c631daSSadaf Ebrahimi   void orr(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2712*f5c631daSSadaf Ebrahimi 
2713*f5c631daSSadaf Ebrahimi   // Bitwise or immediate.
2714*f5c631daSSadaf Ebrahimi   void orr(const VRegister& vd, const int imm8, const int left_shift = 0);
2715*f5c631daSSadaf Ebrahimi 
2716*f5c631daSSadaf Ebrahimi   // Move register to register.
2717*f5c631daSSadaf Ebrahimi   void mov(const VRegister& vd, const VRegister& vn);
2718*f5c631daSSadaf Ebrahimi 
2719*f5c631daSSadaf Ebrahimi   // Bitwise orn.
2720*f5c631daSSadaf Ebrahimi   void orn(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2721*f5c631daSSadaf Ebrahimi 
2722*f5c631daSSadaf Ebrahimi   // Bitwise eor.
2723*f5c631daSSadaf Ebrahimi   void eor(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2724*f5c631daSSadaf Ebrahimi 
2725*f5c631daSSadaf Ebrahimi   // Bit clear immediate.
2726*f5c631daSSadaf Ebrahimi   void bic(const VRegister& vd, const int imm8, const int left_shift = 0);
2727*f5c631daSSadaf Ebrahimi 
2728*f5c631daSSadaf Ebrahimi   // Bit clear.
2729*f5c631daSSadaf Ebrahimi   void bic(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2730*f5c631daSSadaf Ebrahimi 
2731*f5c631daSSadaf Ebrahimi   // Bitwise insert if false.
2732*f5c631daSSadaf Ebrahimi   void bif(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2733*f5c631daSSadaf Ebrahimi 
2734*f5c631daSSadaf Ebrahimi   // Bitwise insert if true.
2735*f5c631daSSadaf Ebrahimi   void bit(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2736*f5c631daSSadaf Ebrahimi 
2737*f5c631daSSadaf Ebrahimi   // Bitwise select.
2738*f5c631daSSadaf Ebrahimi   void bsl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2739*f5c631daSSadaf Ebrahimi 
2740*f5c631daSSadaf Ebrahimi   // Polynomial multiply.
2741*f5c631daSSadaf Ebrahimi   void pmul(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2742*f5c631daSSadaf Ebrahimi 
2743*f5c631daSSadaf Ebrahimi   // Vector move immediate.
2744*f5c631daSSadaf Ebrahimi   void movi(const VRegister& vd,
2745*f5c631daSSadaf Ebrahimi             const uint64_t imm,
2746*f5c631daSSadaf Ebrahimi             Shift shift = LSL,
2747*f5c631daSSadaf Ebrahimi             const int shift_amount = 0);
2748*f5c631daSSadaf Ebrahimi 
2749*f5c631daSSadaf Ebrahimi   // Bitwise not.
2750*f5c631daSSadaf Ebrahimi   void mvn(const VRegister& vd, const VRegister& vn);
2751*f5c631daSSadaf Ebrahimi 
2752*f5c631daSSadaf Ebrahimi   // Vector move inverted immediate.
2753*f5c631daSSadaf Ebrahimi   void mvni(const VRegister& vd,
2754*f5c631daSSadaf Ebrahimi             const int imm8,
2755*f5c631daSSadaf Ebrahimi             Shift shift = LSL,
2756*f5c631daSSadaf Ebrahimi             const int shift_amount = 0);
2757*f5c631daSSadaf Ebrahimi 
2758*f5c631daSSadaf Ebrahimi   // Signed saturating accumulate of unsigned value.
2759*f5c631daSSadaf Ebrahimi   void suqadd(const VRegister& vd, const VRegister& vn);
2760*f5c631daSSadaf Ebrahimi 
2761*f5c631daSSadaf Ebrahimi   // Unsigned saturating accumulate of signed value.
2762*f5c631daSSadaf Ebrahimi   void usqadd(const VRegister& vd, const VRegister& vn);
2763*f5c631daSSadaf Ebrahimi 
2764*f5c631daSSadaf Ebrahimi   // Absolute value.
2765*f5c631daSSadaf Ebrahimi   void abs(const VRegister& vd, const VRegister& vn);
2766*f5c631daSSadaf Ebrahimi 
2767*f5c631daSSadaf Ebrahimi   // Signed saturating absolute value.
2768*f5c631daSSadaf Ebrahimi   void sqabs(const VRegister& vd, const VRegister& vn);
2769*f5c631daSSadaf Ebrahimi 
2770*f5c631daSSadaf Ebrahimi   // Negate.
2771*f5c631daSSadaf Ebrahimi   void neg(const VRegister& vd, const VRegister& vn);
2772*f5c631daSSadaf Ebrahimi 
2773*f5c631daSSadaf Ebrahimi   // Signed saturating negate.
2774*f5c631daSSadaf Ebrahimi   void sqneg(const VRegister& vd, const VRegister& vn);
2775*f5c631daSSadaf Ebrahimi 
2776*f5c631daSSadaf Ebrahimi   // Bitwise not.
2777*f5c631daSSadaf Ebrahimi   void not_(const VRegister& vd, const VRegister& vn);
2778*f5c631daSSadaf Ebrahimi 
2779*f5c631daSSadaf Ebrahimi   // Extract narrow.
2780*f5c631daSSadaf Ebrahimi   void xtn(const VRegister& vd, const VRegister& vn);
2781*f5c631daSSadaf Ebrahimi 
2782*f5c631daSSadaf Ebrahimi   // Extract narrow (second part).
2783*f5c631daSSadaf Ebrahimi   void xtn2(const VRegister& vd, const VRegister& vn);
2784*f5c631daSSadaf Ebrahimi 
2785*f5c631daSSadaf Ebrahimi   // Signed saturating extract narrow.
2786*f5c631daSSadaf Ebrahimi   void sqxtn(const VRegister& vd, const VRegister& vn);
2787*f5c631daSSadaf Ebrahimi 
2788*f5c631daSSadaf Ebrahimi   // Signed saturating extract narrow (second part).
2789*f5c631daSSadaf Ebrahimi   void sqxtn2(const VRegister& vd, const VRegister& vn);
2790*f5c631daSSadaf Ebrahimi 
2791*f5c631daSSadaf Ebrahimi   // Unsigned saturating extract narrow.
2792*f5c631daSSadaf Ebrahimi   void uqxtn(const VRegister& vd, const VRegister& vn);
2793*f5c631daSSadaf Ebrahimi 
2794*f5c631daSSadaf Ebrahimi   // Unsigned saturating extract narrow (second part).
2795*f5c631daSSadaf Ebrahimi   void uqxtn2(const VRegister& vd, const VRegister& vn);
2796*f5c631daSSadaf Ebrahimi 
2797*f5c631daSSadaf Ebrahimi   // Signed saturating extract unsigned narrow.
2798*f5c631daSSadaf Ebrahimi   void sqxtun(const VRegister& vd, const VRegister& vn);
2799*f5c631daSSadaf Ebrahimi 
2800*f5c631daSSadaf Ebrahimi   // Signed saturating extract unsigned narrow (second part).
2801*f5c631daSSadaf Ebrahimi   void sqxtun2(const VRegister& vd, const VRegister& vn);
2802*f5c631daSSadaf Ebrahimi 
2803*f5c631daSSadaf Ebrahimi   // Extract vector from pair of vectors.
2804*f5c631daSSadaf Ebrahimi   void ext(const VRegister& vd,
2805*f5c631daSSadaf Ebrahimi            const VRegister& vn,
2806*f5c631daSSadaf Ebrahimi            const VRegister& vm,
2807*f5c631daSSadaf Ebrahimi            int index);
2808*f5c631daSSadaf Ebrahimi 
2809*f5c631daSSadaf Ebrahimi   // Duplicate vector element to vector or scalar.
2810*f5c631daSSadaf Ebrahimi   void dup(const VRegister& vd, const VRegister& vn, int vn_index);
2811*f5c631daSSadaf Ebrahimi 
2812*f5c631daSSadaf Ebrahimi   // Move vector element to scalar.
2813*f5c631daSSadaf Ebrahimi   void mov(const VRegister& vd, const VRegister& vn, int vn_index);
2814*f5c631daSSadaf Ebrahimi 
2815*f5c631daSSadaf Ebrahimi   // Duplicate general-purpose register to vector.
2816*f5c631daSSadaf Ebrahimi   void dup(const VRegister& vd, const Register& rn);
2817*f5c631daSSadaf Ebrahimi 
2818*f5c631daSSadaf Ebrahimi   // Insert vector element from another vector element.
2819*f5c631daSSadaf Ebrahimi   void ins(const VRegister& vd,
2820*f5c631daSSadaf Ebrahimi            int vd_index,
2821*f5c631daSSadaf Ebrahimi            const VRegister& vn,
2822*f5c631daSSadaf Ebrahimi            int vn_index);
2823*f5c631daSSadaf Ebrahimi 
2824*f5c631daSSadaf Ebrahimi   // Move vector element to another vector element.
2825*f5c631daSSadaf Ebrahimi   void mov(const VRegister& vd,
2826*f5c631daSSadaf Ebrahimi            int vd_index,
2827*f5c631daSSadaf Ebrahimi            const VRegister& vn,
2828*f5c631daSSadaf Ebrahimi            int vn_index);
2829*f5c631daSSadaf Ebrahimi 
2830*f5c631daSSadaf Ebrahimi   // Insert vector element from general-purpose register.
2831*f5c631daSSadaf Ebrahimi   void ins(const VRegister& vd, int vd_index, const Register& rn);
2832*f5c631daSSadaf Ebrahimi 
2833*f5c631daSSadaf Ebrahimi   // Move general-purpose register to a vector element.
2834*f5c631daSSadaf Ebrahimi   void mov(const VRegister& vd, int vd_index, const Register& rn);
2835*f5c631daSSadaf Ebrahimi 
2836*f5c631daSSadaf Ebrahimi   // Unsigned move vector element to general-purpose register.
2837*f5c631daSSadaf Ebrahimi   void umov(const Register& rd, const VRegister& vn, int vn_index);
2838*f5c631daSSadaf Ebrahimi 
2839*f5c631daSSadaf Ebrahimi   // Move vector element to general-purpose register.
2840*f5c631daSSadaf Ebrahimi   void mov(const Register& rd, const VRegister& vn, int vn_index);
2841*f5c631daSSadaf Ebrahimi 
2842*f5c631daSSadaf Ebrahimi   // Signed move vector element to general-purpose register.
2843*f5c631daSSadaf Ebrahimi   void smov(const Register& rd, const VRegister& vn, int vn_index);
2844*f5c631daSSadaf Ebrahimi 
2845*f5c631daSSadaf Ebrahimi   // One-element structure load to one register.
2846*f5c631daSSadaf Ebrahimi   void ld1(const VRegister& vt, const MemOperand& src);
2847*f5c631daSSadaf Ebrahimi 
2848*f5c631daSSadaf Ebrahimi   // One-element structure load to two registers.
2849*f5c631daSSadaf Ebrahimi   void ld1(const VRegister& vt, const VRegister& vt2, const MemOperand& src);
2850*f5c631daSSadaf Ebrahimi 
2851*f5c631daSSadaf Ebrahimi   // One-element structure load to three registers.
2852*f5c631daSSadaf Ebrahimi   void ld1(const VRegister& vt,
2853*f5c631daSSadaf Ebrahimi            const VRegister& vt2,
2854*f5c631daSSadaf Ebrahimi            const VRegister& vt3,
2855*f5c631daSSadaf Ebrahimi            const MemOperand& src);
2856*f5c631daSSadaf Ebrahimi 
2857*f5c631daSSadaf Ebrahimi   // One-element structure load to four registers.
2858*f5c631daSSadaf Ebrahimi   void ld1(const VRegister& vt,
2859*f5c631daSSadaf Ebrahimi            const VRegister& vt2,
2860*f5c631daSSadaf Ebrahimi            const VRegister& vt3,
2861*f5c631daSSadaf Ebrahimi            const VRegister& vt4,
2862*f5c631daSSadaf Ebrahimi            const MemOperand& src);
2863*f5c631daSSadaf Ebrahimi 
2864*f5c631daSSadaf Ebrahimi   // One-element single structure load to one lane.
2865*f5c631daSSadaf Ebrahimi   void ld1(const VRegister& vt, int lane, const MemOperand& src);
2866*f5c631daSSadaf Ebrahimi 
2867*f5c631daSSadaf Ebrahimi   // One-element single structure load to all lanes.
2868*f5c631daSSadaf Ebrahimi   void ld1r(const VRegister& vt, const MemOperand& src);
2869*f5c631daSSadaf Ebrahimi 
2870*f5c631daSSadaf Ebrahimi   // Two-element structure load.
2871*f5c631daSSadaf Ebrahimi   void ld2(const VRegister& vt, const VRegister& vt2, const MemOperand& src);
2872*f5c631daSSadaf Ebrahimi 
2873*f5c631daSSadaf Ebrahimi   // Two-element single structure load to one lane.
2874*f5c631daSSadaf Ebrahimi   void ld2(const VRegister& vt,
2875*f5c631daSSadaf Ebrahimi            const VRegister& vt2,
2876*f5c631daSSadaf Ebrahimi            int lane,
2877*f5c631daSSadaf Ebrahimi            const MemOperand& src);
2878*f5c631daSSadaf Ebrahimi 
2879*f5c631daSSadaf Ebrahimi   // Two-element single structure load to all lanes.
2880*f5c631daSSadaf Ebrahimi   void ld2r(const VRegister& vt, const VRegister& vt2, const MemOperand& src);
2881*f5c631daSSadaf Ebrahimi 
2882*f5c631daSSadaf Ebrahimi   // Three-element structure load.
2883*f5c631daSSadaf Ebrahimi   void ld3(const VRegister& vt,
2884*f5c631daSSadaf Ebrahimi            const VRegister& vt2,
2885*f5c631daSSadaf Ebrahimi            const VRegister& vt3,
2886*f5c631daSSadaf Ebrahimi            const MemOperand& src);
2887*f5c631daSSadaf Ebrahimi 
2888*f5c631daSSadaf Ebrahimi   // Three-element single structure load to one lane.
2889*f5c631daSSadaf Ebrahimi   void ld3(const VRegister& vt,
2890*f5c631daSSadaf Ebrahimi            const VRegister& vt2,
2891*f5c631daSSadaf Ebrahimi            const VRegister& vt3,
2892*f5c631daSSadaf Ebrahimi            int lane,
2893*f5c631daSSadaf Ebrahimi            const MemOperand& src);
2894*f5c631daSSadaf Ebrahimi 
2895*f5c631daSSadaf Ebrahimi   // Three-element single structure load to all lanes.
2896*f5c631daSSadaf Ebrahimi   void ld3r(const VRegister& vt,
2897*f5c631daSSadaf Ebrahimi             const VRegister& vt2,
2898*f5c631daSSadaf Ebrahimi             const VRegister& vt3,
2899*f5c631daSSadaf Ebrahimi             const MemOperand& src);
2900*f5c631daSSadaf Ebrahimi 
2901*f5c631daSSadaf Ebrahimi   // Four-element structure load.
2902*f5c631daSSadaf Ebrahimi   void ld4(const VRegister& vt,
2903*f5c631daSSadaf Ebrahimi            const VRegister& vt2,
2904*f5c631daSSadaf Ebrahimi            const VRegister& vt3,
2905*f5c631daSSadaf Ebrahimi            const VRegister& vt4,
2906*f5c631daSSadaf Ebrahimi            const MemOperand& src);
2907*f5c631daSSadaf Ebrahimi 
2908*f5c631daSSadaf Ebrahimi   // Four-element single structure load to one lane.
2909*f5c631daSSadaf Ebrahimi   void ld4(const VRegister& vt,
2910*f5c631daSSadaf Ebrahimi            const VRegister& vt2,
2911*f5c631daSSadaf Ebrahimi            const VRegister& vt3,
2912*f5c631daSSadaf Ebrahimi            const VRegister& vt4,
2913*f5c631daSSadaf Ebrahimi            int lane,
2914*f5c631daSSadaf Ebrahimi            const MemOperand& src);
2915*f5c631daSSadaf Ebrahimi 
2916*f5c631daSSadaf Ebrahimi   // Four-element single structure load to all lanes.
2917*f5c631daSSadaf Ebrahimi   void ld4r(const VRegister& vt,
2918*f5c631daSSadaf Ebrahimi             const VRegister& vt2,
2919*f5c631daSSadaf Ebrahimi             const VRegister& vt3,
2920*f5c631daSSadaf Ebrahimi             const VRegister& vt4,
2921*f5c631daSSadaf Ebrahimi             const MemOperand& src);
2922*f5c631daSSadaf Ebrahimi 
2923*f5c631daSSadaf Ebrahimi   // Count leading sign bits.
2924*f5c631daSSadaf Ebrahimi   void cls(const VRegister& vd, const VRegister& vn);
2925*f5c631daSSadaf Ebrahimi 
2926*f5c631daSSadaf Ebrahimi   // Count leading zero bits (vector).
2927*f5c631daSSadaf Ebrahimi   void clz(const VRegister& vd, const VRegister& vn);
2928*f5c631daSSadaf Ebrahimi 
2929*f5c631daSSadaf Ebrahimi   // Population count per byte.
2930*f5c631daSSadaf Ebrahimi   void cnt(const VRegister& vd, const VRegister& vn);
2931*f5c631daSSadaf Ebrahimi 
2932*f5c631daSSadaf Ebrahimi   // Reverse bit order.
2933*f5c631daSSadaf Ebrahimi   void rbit(const VRegister& vd, const VRegister& vn);
2934*f5c631daSSadaf Ebrahimi 
2935*f5c631daSSadaf Ebrahimi   // Reverse elements in 16-bit halfwords.
2936*f5c631daSSadaf Ebrahimi   void rev16(const VRegister& vd, const VRegister& vn);
2937*f5c631daSSadaf Ebrahimi 
2938*f5c631daSSadaf Ebrahimi   // Reverse elements in 32-bit words.
2939*f5c631daSSadaf Ebrahimi   void rev32(const VRegister& vd, const VRegister& vn);
2940*f5c631daSSadaf Ebrahimi 
2941*f5c631daSSadaf Ebrahimi   // Reverse elements in 64-bit doublewords.
2942*f5c631daSSadaf Ebrahimi   void rev64(const VRegister& vd, const VRegister& vn);
2943*f5c631daSSadaf Ebrahimi 
2944*f5c631daSSadaf Ebrahimi   // Unsigned reciprocal square root estimate.
2945*f5c631daSSadaf Ebrahimi   void ursqrte(const VRegister& vd, const VRegister& vn);
2946*f5c631daSSadaf Ebrahimi 
2947*f5c631daSSadaf Ebrahimi   // Unsigned reciprocal estimate.
2948*f5c631daSSadaf Ebrahimi   void urecpe(const VRegister& vd, const VRegister& vn);
2949*f5c631daSSadaf Ebrahimi 
2950*f5c631daSSadaf Ebrahimi   // Signed pairwise long add.
2951*f5c631daSSadaf Ebrahimi   void saddlp(const VRegister& vd, const VRegister& vn);
2952*f5c631daSSadaf Ebrahimi 
2953*f5c631daSSadaf Ebrahimi   // Unsigned pairwise long add.
2954*f5c631daSSadaf Ebrahimi   void uaddlp(const VRegister& vd, const VRegister& vn);
2955*f5c631daSSadaf Ebrahimi 
2956*f5c631daSSadaf Ebrahimi   // Signed pairwise long add and accumulate.
2957*f5c631daSSadaf Ebrahimi   void sadalp(const VRegister& vd, const VRegister& vn);
2958*f5c631daSSadaf Ebrahimi 
2959*f5c631daSSadaf Ebrahimi   // Unsigned pairwise long add and accumulate.
2960*f5c631daSSadaf Ebrahimi   void uadalp(const VRegister& vd, const VRegister& vn);
2961*f5c631daSSadaf Ebrahimi 
2962*f5c631daSSadaf Ebrahimi   // Shift left by immediate.
2963*f5c631daSSadaf Ebrahimi   void shl(const VRegister& vd, const VRegister& vn, int shift);
2964*f5c631daSSadaf Ebrahimi 
2965*f5c631daSSadaf Ebrahimi   // Signed saturating shift left by immediate.
2966*f5c631daSSadaf Ebrahimi   void sqshl(const VRegister& vd, const VRegister& vn, int shift);
2967*f5c631daSSadaf Ebrahimi 
2968*f5c631daSSadaf Ebrahimi   // Signed saturating shift left unsigned by immediate.
2969*f5c631daSSadaf Ebrahimi   void sqshlu(const VRegister& vd, const VRegister& vn, int shift);
2970*f5c631daSSadaf Ebrahimi 
2971*f5c631daSSadaf Ebrahimi   // Unsigned saturating shift left by immediate.
2972*f5c631daSSadaf Ebrahimi   void uqshl(const VRegister& vd, const VRegister& vn, int shift);
2973*f5c631daSSadaf Ebrahimi 
2974*f5c631daSSadaf Ebrahimi   // Signed shift left long by immediate.
2975*f5c631daSSadaf Ebrahimi   void sshll(const VRegister& vd, const VRegister& vn, int shift);
2976*f5c631daSSadaf Ebrahimi 
2977*f5c631daSSadaf Ebrahimi   // Signed shift left long by immediate (second part).
2978*f5c631daSSadaf Ebrahimi   void sshll2(const VRegister& vd, const VRegister& vn, int shift);
2979*f5c631daSSadaf Ebrahimi 
2980*f5c631daSSadaf Ebrahimi   // Signed extend long.
2981*f5c631daSSadaf Ebrahimi   void sxtl(const VRegister& vd, const VRegister& vn);
2982*f5c631daSSadaf Ebrahimi 
2983*f5c631daSSadaf Ebrahimi   // Signed extend long (second part).
2984*f5c631daSSadaf Ebrahimi   void sxtl2(const VRegister& vd, const VRegister& vn);
2985*f5c631daSSadaf Ebrahimi 
2986*f5c631daSSadaf Ebrahimi   // Unsigned shift left long by immediate.
2987*f5c631daSSadaf Ebrahimi   void ushll(const VRegister& vd, const VRegister& vn, int shift);
2988*f5c631daSSadaf Ebrahimi 
2989*f5c631daSSadaf Ebrahimi   // Unsigned shift left long by immediate (second part).
2990*f5c631daSSadaf Ebrahimi   void ushll2(const VRegister& vd, const VRegister& vn, int shift);
2991*f5c631daSSadaf Ebrahimi 
2992*f5c631daSSadaf Ebrahimi   // Shift left long by element size.
2993*f5c631daSSadaf Ebrahimi   void shll(const VRegister& vd, const VRegister& vn, int shift);
2994*f5c631daSSadaf Ebrahimi 
2995*f5c631daSSadaf Ebrahimi   // Shift left long by element size (second part).
2996*f5c631daSSadaf Ebrahimi   void shll2(const VRegister& vd, const VRegister& vn, int shift);
2997*f5c631daSSadaf Ebrahimi 
2998*f5c631daSSadaf Ebrahimi   // Unsigned extend long.
2999*f5c631daSSadaf Ebrahimi   void uxtl(const VRegister& vd, const VRegister& vn);
3000*f5c631daSSadaf Ebrahimi 
3001*f5c631daSSadaf Ebrahimi   // Unsigned extend long (second part).
3002*f5c631daSSadaf Ebrahimi   void uxtl2(const VRegister& vd, const VRegister& vn);
3003*f5c631daSSadaf Ebrahimi 
3004*f5c631daSSadaf Ebrahimi   // Shift left by immediate and insert.
3005*f5c631daSSadaf Ebrahimi   void sli(const VRegister& vd, const VRegister& vn, int shift);
3006*f5c631daSSadaf Ebrahimi 
3007*f5c631daSSadaf Ebrahimi   // Shift right by immediate and insert.
3008*f5c631daSSadaf Ebrahimi   void sri(const VRegister& vd, const VRegister& vn, int shift);
3009*f5c631daSSadaf Ebrahimi 
3010*f5c631daSSadaf Ebrahimi   // Signed maximum.
3011*f5c631daSSadaf Ebrahimi   void smax(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3012*f5c631daSSadaf Ebrahimi 
3013*f5c631daSSadaf Ebrahimi   // Signed pairwise maximum.
3014*f5c631daSSadaf Ebrahimi   void smaxp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3015*f5c631daSSadaf Ebrahimi 
3016*f5c631daSSadaf Ebrahimi   // Add across vector.
3017*f5c631daSSadaf Ebrahimi   void addv(const VRegister& vd, const VRegister& vn);
3018*f5c631daSSadaf Ebrahimi 
3019*f5c631daSSadaf Ebrahimi   // Signed add long across vector.
3020*f5c631daSSadaf Ebrahimi   void saddlv(const VRegister& vd, const VRegister& vn);
3021*f5c631daSSadaf Ebrahimi 
3022*f5c631daSSadaf Ebrahimi   // Unsigned add long across vector.
3023*f5c631daSSadaf Ebrahimi   void uaddlv(const VRegister& vd, const VRegister& vn);
3024*f5c631daSSadaf Ebrahimi 
3025*f5c631daSSadaf Ebrahimi   // FP maximum number across vector.
3026*f5c631daSSadaf Ebrahimi   void fmaxnmv(const VRegister& vd, const VRegister& vn);
3027*f5c631daSSadaf Ebrahimi 
3028*f5c631daSSadaf Ebrahimi   // FP maximum across vector.
3029*f5c631daSSadaf Ebrahimi   void fmaxv(const VRegister& vd, const VRegister& vn);
3030*f5c631daSSadaf Ebrahimi 
3031*f5c631daSSadaf Ebrahimi   // FP minimum number across vector.
3032*f5c631daSSadaf Ebrahimi   void fminnmv(const VRegister& vd, const VRegister& vn);
3033*f5c631daSSadaf Ebrahimi 
3034*f5c631daSSadaf Ebrahimi   // FP minimum across vector.
3035*f5c631daSSadaf Ebrahimi   void fminv(const VRegister& vd, const VRegister& vn);
3036*f5c631daSSadaf Ebrahimi 
3037*f5c631daSSadaf Ebrahimi   // Signed maximum across vector.
3038*f5c631daSSadaf Ebrahimi   void smaxv(const VRegister& vd, const VRegister& vn);
3039*f5c631daSSadaf Ebrahimi 
3040*f5c631daSSadaf Ebrahimi   // Signed minimum.
3041*f5c631daSSadaf Ebrahimi   void smin(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3042*f5c631daSSadaf Ebrahimi 
3043*f5c631daSSadaf Ebrahimi   // Signed minimum pairwise.
3044*f5c631daSSadaf Ebrahimi   void sminp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3045*f5c631daSSadaf Ebrahimi 
3046*f5c631daSSadaf Ebrahimi   // Signed minimum across vector.
3047*f5c631daSSadaf Ebrahimi   void sminv(const VRegister& vd, const VRegister& vn);
3048*f5c631daSSadaf Ebrahimi 
3049*f5c631daSSadaf Ebrahimi   // One-element structure store from one register.
3050*f5c631daSSadaf Ebrahimi   void st1(const VRegister& vt, const MemOperand& src);
3051*f5c631daSSadaf Ebrahimi 
3052*f5c631daSSadaf Ebrahimi   // One-element structure store from two registers.
3053*f5c631daSSadaf Ebrahimi   void st1(const VRegister& vt, const VRegister& vt2, const MemOperand& src);
3054*f5c631daSSadaf Ebrahimi 
3055*f5c631daSSadaf Ebrahimi   // One-element structure store from three registers.
3056*f5c631daSSadaf Ebrahimi   void st1(const VRegister& vt,
3057*f5c631daSSadaf Ebrahimi            const VRegister& vt2,
3058*f5c631daSSadaf Ebrahimi            const VRegister& vt3,
3059*f5c631daSSadaf Ebrahimi            const MemOperand& src);
3060*f5c631daSSadaf Ebrahimi 
3061*f5c631daSSadaf Ebrahimi   // One-element structure store from four registers.
3062*f5c631daSSadaf Ebrahimi   void st1(const VRegister& vt,
3063*f5c631daSSadaf Ebrahimi            const VRegister& vt2,
3064*f5c631daSSadaf Ebrahimi            const VRegister& vt3,
3065*f5c631daSSadaf Ebrahimi            const VRegister& vt4,
3066*f5c631daSSadaf Ebrahimi            const MemOperand& src);
3067*f5c631daSSadaf Ebrahimi 
3068*f5c631daSSadaf Ebrahimi   // One-element single structure store from one lane.
3069*f5c631daSSadaf Ebrahimi   void st1(const VRegister& vt, int lane, const MemOperand& src);
3070*f5c631daSSadaf Ebrahimi 
3071*f5c631daSSadaf Ebrahimi   // Two-element structure store from two registers.
3072*f5c631daSSadaf Ebrahimi   void st2(const VRegister& vt, const VRegister& vt2, const MemOperand& src);
3073*f5c631daSSadaf Ebrahimi 
3074*f5c631daSSadaf Ebrahimi   // Two-element single structure store from two lanes.
3075*f5c631daSSadaf Ebrahimi   void st2(const VRegister& vt,
3076*f5c631daSSadaf Ebrahimi            const VRegister& vt2,
3077*f5c631daSSadaf Ebrahimi            int lane,
3078*f5c631daSSadaf Ebrahimi            const MemOperand& src);
3079*f5c631daSSadaf Ebrahimi 
3080*f5c631daSSadaf Ebrahimi   // Three-element structure store from three registers.
3081*f5c631daSSadaf Ebrahimi   void st3(const VRegister& vt,
3082*f5c631daSSadaf Ebrahimi            const VRegister& vt2,
3083*f5c631daSSadaf Ebrahimi            const VRegister& vt3,
3084*f5c631daSSadaf Ebrahimi            const MemOperand& src);
3085*f5c631daSSadaf Ebrahimi 
3086*f5c631daSSadaf Ebrahimi   // Three-element single structure store from three lanes.
3087*f5c631daSSadaf Ebrahimi   void st3(const VRegister& vt,
3088*f5c631daSSadaf Ebrahimi            const VRegister& vt2,
3089*f5c631daSSadaf Ebrahimi            const VRegister& vt3,
3090*f5c631daSSadaf Ebrahimi            int lane,
3091*f5c631daSSadaf Ebrahimi            const MemOperand& src);
3092*f5c631daSSadaf Ebrahimi 
3093*f5c631daSSadaf Ebrahimi   // Four-element structure store from four registers.
3094*f5c631daSSadaf Ebrahimi   void st4(const VRegister& vt,
3095*f5c631daSSadaf Ebrahimi            const VRegister& vt2,
3096*f5c631daSSadaf Ebrahimi            const VRegister& vt3,
3097*f5c631daSSadaf Ebrahimi            const VRegister& vt4,
3098*f5c631daSSadaf Ebrahimi            const MemOperand& src);
3099*f5c631daSSadaf Ebrahimi 
3100*f5c631daSSadaf Ebrahimi   // Four-element single structure store from four lanes.
3101*f5c631daSSadaf Ebrahimi   void st4(const VRegister& vt,
3102*f5c631daSSadaf Ebrahimi            const VRegister& vt2,
3103*f5c631daSSadaf Ebrahimi            const VRegister& vt3,
3104*f5c631daSSadaf Ebrahimi            const VRegister& vt4,
3105*f5c631daSSadaf Ebrahimi            int lane,
3106*f5c631daSSadaf Ebrahimi            const MemOperand& src);
3107*f5c631daSSadaf Ebrahimi 
3108*f5c631daSSadaf Ebrahimi   // Unsigned add long.
3109*f5c631daSSadaf Ebrahimi   void uaddl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3110*f5c631daSSadaf Ebrahimi 
3111*f5c631daSSadaf Ebrahimi   // Unsigned add long (second part).
3112*f5c631daSSadaf Ebrahimi   void uaddl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3113*f5c631daSSadaf Ebrahimi 
3114*f5c631daSSadaf Ebrahimi   // Unsigned add wide.
3115*f5c631daSSadaf Ebrahimi   void uaddw(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3116*f5c631daSSadaf Ebrahimi 
3117*f5c631daSSadaf Ebrahimi   // Unsigned add wide (second part).
3118*f5c631daSSadaf Ebrahimi   void uaddw2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3119*f5c631daSSadaf Ebrahimi 
3120*f5c631daSSadaf Ebrahimi   // Signed add long.
3121*f5c631daSSadaf Ebrahimi   void saddl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3122*f5c631daSSadaf Ebrahimi 
3123*f5c631daSSadaf Ebrahimi   // Signed add long (second part).
3124*f5c631daSSadaf Ebrahimi   void saddl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3125*f5c631daSSadaf Ebrahimi 
3126*f5c631daSSadaf Ebrahimi   // Signed add wide.
3127*f5c631daSSadaf Ebrahimi   void saddw(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3128*f5c631daSSadaf Ebrahimi 
3129*f5c631daSSadaf Ebrahimi   // Signed add wide (second part).
3130*f5c631daSSadaf Ebrahimi   void saddw2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3131*f5c631daSSadaf Ebrahimi 
3132*f5c631daSSadaf Ebrahimi   // Unsigned subtract long.
3133*f5c631daSSadaf Ebrahimi   void usubl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3134*f5c631daSSadaf Ebrahimi 
3135*f5c631daSSadaf Ebrahimi   // Unsigned subtract long (second part).
3136*f5c631daSSadaf Ebrahimi   void usubl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3137*f5c631daSSadaf Ebrahimi 
3138*f5c631daSSadaf Ebrahimi   // Unsigned subtract wide.
3139*f5c631daSSadaf Ebrahimi   void usubw(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3140*f5c631daSSadaf Ebrahimi 
3141*f5c631daSSadaf Ebrahimi   // Unsigned subtract wide (second part).
3142*f5c631daSSadaf Ebrahimi   void usubw2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3143*f5c631daSSadaf Ebrahimi 
3144*f5c631daSSadaf Ebrahimi   // Signed subtract long.
3145*f5c631daSSadaf Ebrahimi   void ssubl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3146*f5c631daSSadaf Ebrahimi 
3147*f5c631daSSadaf Ebrahimi   // Signed subtract long (second part).
3148*f5c631daSSadaf Ebrahimi   void ssubl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3149*f5c631daSSadaf Ebrahimi 
3150*f5c631daSSadaf Ebrahimi   // Signed integer subtract wide.
3151*f5c631daSSadaf Ebrahimi   void ssubw(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3152*f5c631daSSadaf Ebrahimi 
3153*f5c631daSSadaf Ebrahimi   // Signed integer subtract wide (second part).
3154*f5c631daSSadaf Ebrahimi   void ssubw2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3155*f5c631daSSadaf Ebrahimi 
3156*f5c631daSSadaf Ebrahimi   // Unsigned maximum.
3157*f5c631daSSadaf Ebrahimi   void umax(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3158*f5c631daSSadaf Ebrahimi 
3159*f5c631daSSadaf Ebrahimi   // Unsigned pairwise maximum.
3160*f5c631daSSadaf Ebrahimi   void umaxp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3161*f5c631daSSadaf Ebrahimi 
3162*f5c631daSSadaf Ebrahimi   // Unsigned maximum across vector.
3163*f5c631daSSadaf Ebrahimi   void umaxv(const VRegister& vd, const VRegister& vn);
3164*f5c631daSSadaf Ebrahimi 
3165*f5c631daSSadaf Ebrahimi   // Unsigned minimum.
3166*f5c631daSSadaf Ebrahimi   void umin(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3167*f5c631daSSadaf Ebrahimi 
3168*f5c631daSSadaf Ebrahimi   // Unsigned pairwise minimum.
3169*f5c631daSSadaf Ebrahimi   void uminp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3170*f5c631daSSadaf Ebrahimi 
3171*f5c631daSSadaf Ebrahimi   // Unsigned minimum across vector.
3172*f5c631daSSadaf Ebrahimi   void uminv(const VRegister& vd, const VRegister& vn);
3173*f5c631daSSadaf Ebrahimi 
3174*f5c631daSSadaf Ebrahimi   // Transpose vectors (primary).
3175*f5c631daSSadaf Ebrahimi   void trn1(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3176*f5c631daSSadaf Ebrahimi 
3177*f5c631daSSadaf Ebrahimi   // Transpose vectors (secondary).
3178*f5c631daSSadaf Ebrahimi   void trn2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3179*f5c631daSSadaf Ebrahimi 
3180*f5c631daSSadaf Ebrahimi   // Unzip vectors (primary).
3181*f5c631daSSadaf Ebrahimi   void uzp1(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3182*f5c631daSSadaf Ebrahimi 
3183*f5c631daSSadaf Ebrahimi   // Unzip vectors (secondary).
3184*f5c631daSSadaf Ebrahimi   void uzp2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3185*f5c631daSSadaf Ebrahimi 
3186*f5c631daSSadaf Ebrahimi   // Zip vectors (primary).
3187*f5c631daSSadaf Ebrahimi   void zip1(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3188*f5c631daSSadaf Ebrahimi 
3189*f5c631daSSadaf Ebrahimi   // Zip vectors (secondary).
3190*f5c631daSSadaf Ebrahimi   void zip2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3191*f5c631daSSadaf Ebrahimi 
3192*f5c631daSSadaf Ebrahimi   // Signed shift right by immediate.
3193*f5c631daSSadaf Ebrahimi   void sshr(const VRegister& vd, const VRegister& vn, int shift);
3194*f5c631daSSadaf Ebrahimi 
3195*f5c631daSSadaf Ebrahimi   // Unsigned shift right by immediate.
3196*f5c631daSSadaf Ebrahimi   void ushr(const VRegister& vd, const VRegister& vn, int shift);
3197*f5c631daSSadaf Ebrahimi 
3198*f5c631daSSadaf Ebrahimi   // Signed rounding shift right by immediate.
3199*f5c631daSSadaf Ebrahimi   void srshr(const VRegister& vd, const VRegister& vn, int shift);
3200*f5c631daSSadaf Ebrahimi 
3201*f5c631daSSadaf Ebrahimi   // Unsigned rounding shift right by immediate.
3202*f5c631daSSadaf Ebrahimi   void urshr(const VRegister& vd, const VRegister& vn, int shift);
3203*f5c631daSSadaf Ebrahimi 
3204*f5c631daSSadaf Ebrahimi   // Signed shift right by immediate and accumulate.
3205*f5c631daSSadaf Ebrahimi   void ssra(const VRegister& vd, const VRegister& vn, int shift);
3206*f5c631daSSadaf Ebrahimi 
3207*f5c631daSSadaf Ebrahimi   // Unsigned shift right by immediate and accumulate.
3208*f5c631daSSadaf Ebrahimi   void usra(const VRegister& vd, const VRegister& vn, int shift);
3209*f5c631daSSadaf Ebrahimi 
3210*f5c631daSSadaf Ebrahimi   // Signed rounding shift right by immediate and accumulate.
3211*f5c631daSSadaf Ebrahimi   void srsra(const VRegister& vd, const VRegister& vn, int shift);
3212*f5c631daSSadaf Ebrahimi 
3213*f5c631daSSadaf Ebrahimi   // Unsigned rounding shift right by immediate and accumulate.
3214*f5c631daSSadaf Ebrahimi   void ursra(const VRegister& vd, const VRegister& vn, int shift);
3215*f5c631daSSadaf Ebrahimi 
3216*f5c631daSSadaf Ebrahimi   // Shift right narrow by immediate.
3217*f5c631daSSadaf Ebrahimi   void shrn(const VRegister& vd, const VRegister& vn, int shift);
3218*f5c631daSSadaf Ebrahimi 
3219*f5c631daSSadaf Ebrahimi   // Shift right narrow by immediate (second part).
3220*f5c631daSSadaf Ebrahimi   void shrn2(const VRegister& vd, const VRegister& vn, int shift);
3221*f5c631daSSadaf Ebrahimi 
3222*f5c631daSSadaf Ebrahimi   // Rounding shift right narrow by immediate.
3223*f5c631daSSadaf Ebrahimi   void rshrn(const VRegister& vd, const VRegister& vn, int shift);
3224*f5c631daSSadaf Ebrahimi 
3225*f5c631daSSadaf Ebrahimi   // Rounding shift right narrow by immediate (second part).
3226*f5c631daSSadaf Ebrahimi   void rshrn2(const VRegister& vd, const VRegister& vn, int shift);
3227*f5c631daSSadaf Ebrahimi 
3228*f5c631daSSadaf Ebrahimi   // Unsigned saturating shift right narrow by immediate.
3229*f5c631daSSadaf Ebrahimi   void uqshrn(const VRegister& vd, const VRegister& vn, int shift);
3230*f5c631daSSadaf Ebrahimi 
3231*f5c631daSSadaf Ebrahimi   // Unsigned saturating shift right narrow by immediate (second part).
3232*f5c631daSSadaf Ebrahimi   void uqshrn2(const VRegister& vd, const VRegister& vn, int shift);
3233*f5c631daSSadaf Ebrahimi 
3234*f5c631daSSadaf Ebrahimi   // Unsigned saturating rounding shift right narrow by immediate.
3235*f5c631daSSadaf Ebrahimi   void uqrshrn(const VRegister& vd, const VRegister& vn, int shift);
3236*f5c631daSSadaf Ebrahimi 
3237*f5c631daSSadaf Ebrahimi   // Unsigned saturating rounding shift right narrow by immediate (second part).
3238*f5c631daSSadaf Ebrahimi   void uqrshrn2(const VRegister& vd, const VRegister& vn, int shift);
3239*f5c631daSSadaf Ebrahimi 
3240*f5c631daSSadaf Ebrahimi   // Signed saturating shift right narrow by immediate.
3241*f5c631daSSadaf Ebrahimi   void sqshrn(const VRegister& vd, const VRegister& vn, int shift);
3242*f5c631daSSadaf Ebrahimi 
3243*f5c631daSSadaf Ebrahimi   // Signed saturating shift right narrow by immediate (second part).
3244*f5c631daSSadaf Ebrahimi   void sqshrn2(const VRegister& vd, const VRegister& vn, int shift);
3245*f5c631daSSadaf Ebrahimi 
3246*f5c631daSSadaf Ebrahimi   // Signed saturating rounded shift right narrow by immediate.
3247*f5c631daSSadaf Ebrahimi   void sqrshrn(const VRegister& vd, const VRegister& vn, int shift);
3248*f5c631daSSadaf Ebrahimi 
3249*f5c631daSSadaf Ebrahimi   // Signed saturating rounded shift right narrow by immediate (second part).
3250*f5c631daSSadaf Ebrahimi   void sqrshrn2(const VRegister& vd, const VRegister& vn, int shift);
3251*f5c631daSSadaf Ebrahimi 
3252*f5c631daSSadaf Ebrahimi   // Signed saturating shift right unsigned narrow by immediate.
3253*f5c631daSSadaf Ebrahimi   void sqshrun(const VRegister& vd, const VRegister& vn, int shift);
3254*f5c631daSSadaf Ebrahimi 
3255*f5c631daSSadaf Ebrahimi   // Signed saturating shift right unsigned narrow by immediate (second part).
3256*f5c631daSSadaf Ebrahimi   void sqshrun2(const VRegister& vd, const VRegister& vn, int shift);
3257*f5c631daSSadaf Ebrahimi 
3258*f5c631daSSadaf Ebrahimi   // Signed sat rounded shift right unsigned narrow by immediate.
3259*f5c631daSSadaf Ebrahimi   void sqrshrun(const VRegister& vd, const VRegister& vn, int shift);
3260*f5c631daSSadaf Ebrahimi 
3261*f5c631daSSadaf Ebrahimi   // Signed sat rounded shift right unsigned narrow by immediate (second part).
3262*f5c631daSSadaf Ebrahimi   void sqrshrun2(const VRegister& vd, const VRegister& vn, int shift);
3263*f5c631daSSadaf Ebrahimi 
3264*f5c631daSSadaf Ebrahimi   // FP reciprocal step.
3265*f5c631daSSadaf Ebrahimi   void frecps(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3266*f5c631daSSadaf Ebrahimi 
3267*f5c631daSSadaf Ebrahimi   // FP reciprocal estimate.
3268*f5c631daSSadaf Ebrahimi   void frecpe(const VRegister& vd, const VRegister& vn);
3269*f5c631daSSadaf Ebrahimi 
3270*f5c631daSSadaf Ebrahimi   // FP reciprocal square root estimate.
3271*f5c631daSSadaf Ebrahimi   void frsqrte(const VRegister& vd, const VRegister& vn);
3272*f5c631daSSadaf Ebrahimi 
3273*f5c631daSSadaf Ebrahimi   // FP reciprocal square root step.
3274*f5c631daSSadaf Ebrahimi   void frsqrts(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3275*f5c631daSSadaf Ebrahimi 
3276*f5c631daSSadaf Ebrahimi   // Signed absolute difference and accumulate long.
3277*f5c631daSSadaf Ebrahimi   void sabal(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3278*f5c631daSSadaf Ebrahimi 
3279*f5c631daSSadaf Ebrahimi   // Signed absolute difference and accumulate long (second part).
3280*f5c631daSSadaf Ebrahimi   void sabal2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3281*f5c631daSSadaf Ebrahimi 
3282*f5c631daSSadaf Ebrahimi   // Unsigned absolute difference and accumulate long.
3283*f5c631daSSadaf Ebrahimi   void uabal(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3284*f5c631daSSadaf Ebrahimi 
3285*f5c631daSSadaf Ebrahimi   // Unsigned absolute difference and accumulate long (second part).
3286*f5c631daSSadaf Ebrahimi   void uabal2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3287*f5c631daSSadaf Ebrahimi 
3288*f5c631daSSadaf Ebrahimi   // Signed absolute difference long.
3289*f5c631daSSadaf Ebrahimi   void sabdl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3290*f5c631daSSadaf Ebrahimi 
3291*f5c631daSSadaf Ebrahimi   // Signed absolute difference long (second part).
3292*f5c631daSSadaf Ebrahimi   void sabdl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3293*f5c631daSSadaf Ebrahimi 
3294*f5c631daSSadaf Ebrahimi   // Unsigned absolute difference long.
3295*f5c631daSSadaf Ebrahimi   void uabdl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3296*f5c631daSSadaf Ebrahimi 
3297*f5c631daSSadaf Ebrahimi   // Unsigned absolute difference long (second part).
3298*f5c631daSSadaf Ebrahimi   void uabdl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3299*f5c631daSSadaf Ebrahimi 
3300*f5c631daSSadaf Ebrahimi   // Polynomial multiply long.
3301*f5c631daSSadaf Ebrahimi   void pmull(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3302*f5c631daSSadaf Ebrahimi 
3303*f5c631daSSadaf Ebrahimi   // Polynomial multiply long (second part).
3304*f5c631daSSadaf Ebrahimi   void pmull2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3305*f5c631daSSadaf Ebrahimi 
3306*f5c631daSSadaf Ebrahimi   // Signed long multiply-add.
3307*f5c631daSSadaf Ebrahimi   void smlal(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3308*f5c631daSSadaf Ebrahimi 
3309*f5c631daSSadaf Ebrahimi   // Signed long multiply-add (second part).
3310*f5c631daSSadaf Ebrahimi   void smlal2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3311*f5c631daSSadaf Ebrahimi 
3312*f5c631daSSadaf Ebrahimi   // Unsigned long multiply-add.
3313*f5c631daSSadaf Ebrahimi   void umlal(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3314*f5c631daSSadaf Ebrahimi 
3315*f5c631daSSadaf Ebrahimi   // Unsigned long multiply-add (second part).
3316*f5c631daSSadaf Ebrahimi   void umlal2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3317*f5c631daSSadaf Ebrahimi 
3318*f5c631daSSadaf Ebrahimi   // Signed long multiply-sub.
3319*f5c631daSSadaf Ebrahimi   void smlsl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3320*f5c631daSSadaf Ebrahimi 
3321*f5c631daSSadaf Ebrahimi   // Signed long multiply-sub (second part).
3322*f5c631daSSadaf Ebrahimi   void smlsl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3323*f5c631daSSadaf Ebrahimi 
3324*f5c631daSSadaf Ebrahimi   // Unsigned long multiply-sub.
3325*f5c631daSSadaf Ebrahimi   void umlsl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3326*f5c631daSSadaf Ebrahimi 
3327*f5c631daSSadaf Ebrahimi   // Unsigned long multiply-sub (second part).
3328*f5c631daSSadaf Ebrahimi   void umlsl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3329*f5c631daSSadaf Ebrahimi 
3330*f5c631daSSadaf Ebrahimi   // Signed long multiply.
3331*f5c631daSSadaf Ebrahimi   void smull(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3332*f5c631daSSadaf Ebrahimi 
3333*f5c631daSSadaf Ebrahimi   // Signed long multiply (second part).
3334*f5c631daSSadaf Ebrahimi   void smull2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3335*f5c631daSSadaf Ebrahimi 
3336*f5c631daSSadaf Ebrahimi   // Signed saturating doubling long multiply-add.
3337*f5c631daSSadaf Ebrahimi   void sqdmlal(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3338*f5c631daSSadaf Ebrahimi 
3339*f5c631daSSadaf Ebrahimi   // Signed saturating doubling long multiply-add (second part).
3340*f5c631daSSadaf Ebrahimi   void sqdmlal2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3341*f5c631daSSadaf Ebrahimi 
3342*f5c631daSSadaf Ebrahimi   // Signed saturating doubling long multiply-subtract.
3343*f5c631daSSadaf Ebrahimi   void sqdmlsl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3344*f5c631daSSadaf Ebrahimi 
3345*f5c631daSSadaf Ebrahimi   // Signed saturating doubling long multiply-subtract (second part).
3346*f5c631daSSadaf Ebrahimi   void sqdmlsl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3347*f5c631daSSadaf Ebrahimi 
3348*f5c631daSSadaf Ebrahimi   // Signed saturating doubling long multiply.
3349*f5c631daSSadaf Ebrahimi   void sqdmull(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3350*f5c631daSSadaf Ebrahimi 
3351*f5c631daSSadaf Ebrahimi   // Signed saturating doubling long multiply (second part).
3352*f5c631daSSadaf Ebrahimi   void sqdmull2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3353*f5c631daSSadaf Ebrahimi 
3354*f5c631daSSadaf Ebrahimi   // Signed saturating doubling multiply returning high half.
3355*f5c631daSSadaf Ebrahimi   void sqdmulh(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3356*f5c631daSSadaf Ebrahimi 
3357*f5c631daSSadaf Ebrahimi   // Signed saturating rounding doubling multiply returning high half.
3358*f5c631daSSadaf Ebrahimi   void sqrdmulh(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3359*f5c631daSSadaf Ebrahimi 
3360*f5c631daSSadaf Ebrahimi   // Signed dot product [Armv8.2].
3361*f5c631daSSadaf Ebrahimi   void sdot(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3362*f5c631daSSadaf Ebrahimi 
3363*f5c631daSSadaf Ebrahimi   // Signed saturating rounding doubling multiply accumulate returning high
3364*f5c631daSSadaf Ebrahimi   // half [Armv8.1].
3365*f5c631daSSadaf Ebrahimi   void sqrdmlah(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3366*f5c631daSSadaf Ebrahimi 
3367*f5c631daSSadaf Ebrahimi   // Unsigned dot product [Armv8.2].
3368*f5c631daSSadaf Ebrahimi   void udot(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3369*f5c631daSSadaf Ebrahimi 
3370*f5c631daSSadaf Ebrahimi   // Dot Product with unsigned and signed integers (vector).
3371*f5c631daSSadaf Ebrahimi   void usdot(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3372*f5c631daSSadaf Ebrahimi 
3373*f5c631daSSadaf Ebrahimi   // Dot product with signed and unsigned integers (vector, by element).
3374*f5c631daSSadaf Ebrahimi   void sudot(const VRegister& vd,
3375*f5c631daSSadaf Ebrahimi              const VRegister& vn,
3376*f5c631daSSadaf Ebrahimi              const VRegister& vm,
3377*f5c631daSSadaf Ebrahimi              int vm_index);
3378*f5c631daSSadaf Ebrahimi 
3379*f5c631daSSadaf Ebrahimi   // Dot product with unsigned and signed integers (vector, by element).
3380*f5c631daSSadaf Ebrahimi   void usdot(const VRegister& vd,
3381*f5c631daSSadaf Ebrahimi              const VRegister& vn,
3382*f5c631daSSadaf Ebrahimi              const VRegister& vm,
3383*f5c631daSSadaf Ebrahimi              int vm_index);
3384*f5c631daSSadaf Ebrahimi 
3385*f5c631daSSadaf Ebrahimi   // Signed saturating rounding doubling multiply subtract returning high half
3386*f5c631daSSadaf Ebrahimi   // [Armv8.1].
3387*f5c631daSSadaf Ebrahimi   void sqrdmlsh(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3388*f5c631daSSadaf Ebrahimi 
3389*f5c631daSSadaf Ebrahimi   // Signed saturating doubling multiply element returning high half.
3390*f5c631daSSadaf Ebrahimi   void sqdmulh(const VRegister& vd,
3391*f5c631daSSadaf Ebrahimi                const VRegister& vn,
3392*f5c631daSSadaf Ebrahimi                const VRegister& vm,
3393*f5c631daSSadaf Ebrahimi                int vm_index);
3394*f5c631daSSadaf Ebrahimi 
3395*f5c631daSSadaf Ebrahimi   // Signed saturating rounding doubling multiply element returning high half.
3396*f5c631daSSadaf Ebrahimi   void sqrdmulh(const VRegister& vd,
3397*f5c631daSSadaf Ebrahimi                 const VRegister& vn,
3398*f5c631daSSadaf Ebrahimi                 const VRegister& vm,
3399*f5c631daSSadaf Ebrahimi                 int vm_index);
3400*f5c631daSSadaf Ebrahimi 
3401*f5c631daSSadaf Ebrahimi   // Signed dot product by element [Armv8.2].
3402*f5c631daSSadaf Ebrahimi   void sdot(const VRegister& vd,
3403*f5c631daSSadaf Ebrahimi             const VRegister& vn,
3404*f5c631daSSadaf Ebrahimi             const VRegister& vm,
3405*f5c631daSSadaf Ebrahimi             int vm_index);
3406*f5c631daSSadaf Ebrahimi 
3407*f5c631daSSadaf Ebrahimi   // Signed saturating rounding doubling multiply accumulate element returning
3408*f5c631daSSadaf Ebrahimi   // high half [Armv8.1].
3409*f5c631daSSadaf Ebrahimi   void sqrdmlah(const VRegister& vd,
3410*f5c631daSSadaf Ebrahimi                 const VRegister& vn,
3411*f5c631daSSadaf Ebrahimi                 const VRegister& vm,
3412*f5c631daSSadaf Ebrahimi                 int vm_index);
3413*f5c631daSSadaf Ebrahimi 
3414*f5c631daSSadaf Ebrahimi   // Unsigned dot product by element [Armv8.2].
3415*f5c631daSSadaf Ebrahimi   void udot(const VRegister& vd,
3416*f5c631daSSadaf Ebrahimi             const VRegister& vn,
3417*f5c631daSSadaf Ebrahimi             const VRegister& vm,
3418*f5c631daSSadaf Ebrahimi             int vm_index);
3419*f5c631daSSadaf Ebrahimi 
3420*f5c631daSSadaf Ebrahimi   // Signed saturating rounding doubling multiply subtract element returning
3421*f5c631daSSadaf Ebrahimi   // high half [Armv8.1].
3422*f5c631daSSadaf Ebrahimi   void sqrdmlsh(const VRegister& vd,
3423*f5c631daSSadaf Ebrahimi                 const VRegister& vn,
3424*f5c631daSSadaf Ebrahimi                 const VRegister& vm,
3425*f5c631daSSadaf Ebrahimi                 int vm_index);
3426*f5c631daSSadaf Ebrahimi 
3427*f5c631daSSadaf Ebrahimi   // Unsigned long multiply long.
3428*f5c631daSSadaf Ebrahimi   void umull(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3429*f5c631daSSadaf Ebrahimi 
3430*f5c631daSSadaf Ebrahimi   // Unsigned long multiply (second part).
3431*f5c631daSSadaf Ebrahimi   void umull2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3432*f5c631daSSadaf Ebrahimi 
3433*f5c631daSSadaf Ebrahimi   // Add narrow returning high half.
3434*f5c631daSSadaf Ebrahimi   void addhn(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3435*f5c631daSSadaf Ebrahimi 
3436*f5c631daSSadaf Ebrahimi   // Add narrow returning high half (second part).
3437*f5c631daSSadaf Ebrahimi   void addhn2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3438*f5c631daSSadaf Ebrahimi 
3439*f5c631daSSadaf Ebrahimi   // Rounding add narrow returning high half.
3440*f5c631daSSadaf Ebrahimi   void raddhn(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3441*f5c631daSSadaf Ebrahimi 
3442*f5c631daSSadaf Ebrahimi   // Rounding add narrow returning high half (second part).
3443*f5c631daSSadaf Ebrahimi   void raddhn2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3444*f5c631daSSadaf Ebrahimi 
3445*f5c631daSSadaf Ebrahimi   // Subtract narrow returning high half.
3446*f5c631daSSadaf Ebrahimi   void subhn(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3447*f5c631daSSadaf Ebrahimi 
3448*f5c631daSSadaf Ebrahimi   // Subtract narrow returning high half (second part).
3449*f5c631daSSadaf Ebrahimi   void subhn2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3450*f5c631daSSadaf Ebrahimi 
3451*f5c631daSSadaf Ebrahimi   // Rounding subtract narrow returning high half.
3452*f5c631daSSadaf Ebrahimi   void rsubhn(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3453*f5c631daSSadaf Ebrahimi 
3454*f5c631daSSadaf Ebrahimi   // Rounding subtract narrow returning high half (second part).
3455*f5c631daSSadaf Ebrahimi   void rsubhn2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3456*f5c631daSSadaf Ebrahimi 
3457*f5c631daSSadaf Ebrahimi   // FP vector multiply accumulate.
3458*f5c631daSSadaf Ebrahimi   void fmla(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3459*f5c631daSSadaf Ebrahimi 
3460*f5c631daSSadaf Ebrahimi   // FP fused multiply-add long to accumulator.
3461*f5c631daSSadaf Ebrahimi   void fmlal(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3462*f5c631daSSadaf Ebrahimi 
3463*f5c631daSSadaf Ebrahimi   // FP fused multiply-add long to accumulator (second part).
3464*f5c631daSSadaf Ebrahimi   void fmlal2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3465*f5c631daSSadaf Ebrahimi 
3466*f5c631daSSadaf Ebrahimi   // FP fused multiply-add long to accumulator by element.
3467*f5c631daSSadaf Ebrahimi   void fmlal(const VRegister& vd,
3468*f5c631daSSadaf Ebrahimi              const VRegister& vn,
3469*f5c631daSSadaf Ebrahimi              const VRegister& vm,
3470*f5c631daSSadaf Ebrahimi              int vm_index);
3471*f5c631daSSadaf Ebrahimi 
3472*f5c631daSSadaf Ebrahimi   // FP fused multiply-add long to accumulator by element (second part).
3473*f5c631daSSadaf Ebrahimi   void fmlal2(const VRegister& vd,
3474*f5c631daSSadaf Ebrahimi               const VRegister& vn,
3475*f5c631daSSadaf Ebrahimi               const VRegister& vm,
3476*f5c631daSSadaf Ebrahimi               int vm_index);
3477*f5c631daSSadaf Ebrahimi 
3478*f5c631daSSadaf Ebrahimi   // FP vector multiply subtract.
3479*f5c631daSSadaf Ebrahimi   void fmls(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3480*f5c631daSSadaf Ebrahimi 
3481*f5c631daSSadaf Ebrahimi   // FP fused multiply-subtract long to accumulator.
3482*f5c631daSSadaf Ebrahimi   void fmlsl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3483*f5c631daSSadaf Ebrahimi 
3484*f5c631daSSadaf Ebrahimi   // FP fused multiply-subtract long to accumulator (second part).
3485*f5c631daSSadaf Ebrahimi   void fmlsl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3486*f5c631daSSadaf Ebrahimi 
3487*f5c631daSSadaf Ebrahimi   // FP fused multiply-subtract long to accumulator by element.
3488*f5c631daSSadaf Ebrahimi   void fmlsl(const VRegister& vd,
3489*f5c631daSSadaf Ebrahimi              const VRegister& vn,
3490*f5c631daSSadaf Ebrahimi              const VRegister& vm,
3491*f5c631daSSadaf Ebrahimi              int vm_index);
3492*f5c631daSSadaf Ebrahimi 
3493*f5c631daSSadaf Ebrahimi   // FP fused multiply-subtract long to accumulator by element (second part).
3494*f5c631daSSadaf Ebrahimi   void fmlsl2(const VRegister& vd,
3495*f5c631daSSadaf Ebrahimi               const VRegister& vn,
3496*f5c631daSSadaf Ebrahimi               const VRegister& vm,
3497*f5c631daSSadaf Ebrahimi               int vm_index);
3498*f5c631daSSadaf Ebrahimi 
3499*f5c631daSSadaf Ebrahimi   // FP vector multiply extended.
3500*f5c631daSSadaf Ebrahimi   void fmulx(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3501*f5c631daSSadaf Ebrahimi 
3502*f5c631daSSadaf Ebrahimi   // FP absolute greater than or equal.
3503*f5c631daSSadaf Ebrahimi   void facge(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3504*f5c631daSSadaf Ebrahimi 
3505*f5c631daSSadaf Ebrahimi   // FP absolute greater than.
3506*f5c631daSSadaf Ebrahimi   void facgt(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3507*f5c631daSSadaf Ebrahimi 
3508*f5c631daSSadaf Ebrahimi   // FP multiply by element.
3509*f5c631daSSadaf Ebrahimi   void fmul(const VRegister& vd,
3510*f5c631daSSadaf Ebrahimi             const VRegister& vn,
3511*f5c631daSSadaf Ebrahimi             const VRegister& vm,
3512*f5c631daSSadaf Ebrahimi             int vm_index);
3513*f5c631daSSadaf Ebrahimi 
3514*f5c631daSSadaf Ebrahimi   // FP fused multiply-add to accumulator by element.
3515*f5c631daSSadaf Ebrahimi   void fmla(const VRegister& vd,
3516*f5c631daSSadaf Ebrahimi             const VRegister& vn,
3517*f5c631daSSadaf Ebrahimi             const VRegister& vm,
3518*f5c631daSSadaf Ebrahimi             int vm_index);
3519*f5c631daSSadaf Ebrahimi 
3520*f5c631daSSadaf Ebrahimi   // FP fused multiply-sub from accumulator by element.
3521*f5c631daSSadaf Ebrahimi   void fmls(const VRegister& vd,
3522*f5c631daSSadaf Ebrahimi             const VRegister& vn,
3523*f5c631daSSadaf Ebrahimi             const VRegister& vm,
3524*f5c631daSSadaf Ebrahimi             int vm_index);
3525*f5c631daSSadaf Ebrahimi 
3526*f5c631daSSadaf Ebrahimi   // FP multiply extended by element.
3527*f5c631daSSadaf Ebrahimi   void fmulx(const VRegister& vd,
3528*f5c631daSSadaf Ebrahimi              const VRegister& vn,
3529*f5c631daSSadaf Ebrahimi              const VRegister& vm,
3530*f5c631daSSadaf Ebrahimi              int vm_index);
3531*f5c631daSSadaf Ebrahimi 
3532*f5c631daSSadaf Ebrahimi   // FP compare equal.
3533*f5c631daSSadaf Ebrahimi   void fcmeq(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3534*f5c631daSSadaf Ebrahimi 
3535*f5c631daSSadaf Ebrahimi   // FP greater than.
3536*f5c631daSSadaf Ebrahimi   void fcmgt(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3537*f5c631daSSadaf Ebrahimi 
3538*f5c631daSSadaf Ebrahimi   // FP greater than or equal.
3539*f5c631daSSadaf Ebrahimi   void fcmge(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3540*f5c631daSSadaf Ebrahimi 
3541*f5c631daSSadaf Ebrahimi   // FP compare equal to zero.
3542*f5c631daSSadaf Ebrahimi   void fcmeq(const VRegister& vd, const VRegister& vn, double imm);
3543*f5c631daSSadaf Ebrahimi 
3544*f5c631daSSadaf Ebrahimi   // FP greater than zero.
3545*f5c631daSSadaf Ebrahimi   void fcmgt(const VRegister& vd, const VRegister& vn, double imm);
3546*f5c631daSSadaf Ebrahimi 
3547*f5c631daSSadaf Ebrahimi   // FP greater than or equal to zero.
3548*f5c631daSSadaf Ebrahimi   void fcmge(const VRegister& vd, const VRegister& vn, double imm);
3549*f5c631daSSadaf Ebrahimi 
3550*f5c631daSSadaf Ebrahimi   // FP less than or equal to zero.
3551*f5c631daSSadaf Ebrahimi   void fcmle(const VRegister& vd, const VRegister& vn, double imm);
3552*f5c631daSSadaf Ebrahimi 
3553*f5c631daSSadaf Ebrahimi   // FP less than to zero.
3554*f5c631daSSadaf Ebrahimi   void fcmlt(const VRegister& vd, const VRegister& vn, double imm);
3555*f5c631daSSadaf Ebrahimi 
3556*f5c631daSSadaf Ebrahimi   // FP absolute difference.
3557*f5c631daSSadaf Ebrahimi   void fabd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3558*f5c631daSSadaf Ebrahimi 
3559*f5c631daSSadaf Ebrahimi   // FP pairwise add vector.
3560*f5c631daSSadaf Ebrahimi   void faddp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3561*f5c631daSSadaf Ebrahimi 
3562*f5c631daSSadaf Ebrahimi   // FP pairwise add scalar.
3563*f5c631daSSadaf Ebrahimi   void faddp(const VRegister& vd, const VRegister& vn);
3564*f5c631daSSadaf Ebrahimi 
3565*f5c631daSSadaf Ebrahimi   // FP pairwise maximum vector.
3566*f5c631daSSadaf Ebrahimi   void fmaxp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3567*f5c631daSSadaf Ebrahimi 
3568*f5c631daSSadaf Ebrahimi   // FP pairwise maximum scalar.
3569*f5c631daSSadaf Ebrahimi   void fmaxp(const VRegister& vd, const VRegister& vn);
3570*f5c631daSSadaf Ebrahimi 
3571*f5c631daSSadaf Ebrahimi   // FP pairwise minimum vector.
3572*f5c631daSSadaf Ebrahimi   void fminp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3573*f5c631daSSadaf Ebrahimi 
3574*f5c631daSSadaf Ebrahimi   // FP pairwise minimum scalar.
3575*f5c631daSSadaf Ebrahimi   void fminp(const VRegister& vd, const VRegister& vn);
3576*f5c631daSSadaf Ebrahimi 
3577*f5c631daSSadaf Ebrahimi   // FP pairwise maximum number vector.
3578*f5c631daSSadaf Ebrahimi   void fmaxnmp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3579*f5c631daSSadaf Ebrahimi 
3580*f5c631daSSadaf Ebrahimi   // FP pairwise maximum number scalar.
3581*f5c631daSSadaf Ebrahimi   void fmaxnmp(const VRegister& vd, const VRegister& vn);
3582*f5c631daSSadaf Ebrahimi 
3583*f5c631daSSadaf Ebrahimi   // FP pairwise minimum number vector.
3584*f5c631daSSadaf Ebrahimi   void fminnmp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3585*f5c631daSSadaf Ebrahimi 
3586*f5c631daSSadaf Ebrahimi   // FP pairwise minimum number scalar.
3587*f5c631daSSadaf Ebrahimi   void fminnmp(const VRegister& vd, const VRegister& vn);
3588*f5c631daSSadaf Ebrahimi 
3589*f5c631daSSadaf Ebrahimi   // v8.3 complex numbers - note that these are only partial/helper functions
3590*f5c631daSSadaf Ebrahimi   // and must be used in series in order to perform full CN operations.
3591*f5c631daSSadaf Ebrahimi 
3592*f5c631daSSadaf Ebrahimi   // FP complex multiply accumulate (by element) [Armv8.3].
3593*f5c631daSSadaf Ebrahimi   void fcmla(const VRegister& vd,
3594*f5c631daSSadaf Ebrahimi              const VRegister& vn,
3595*f5c631daSSadaf Ebrahimi              const VRegister& vm,
3596*f5c631daSSadaf Ebrahimi              int vm_index,
3597*f5c631daSSadaf Ebrahimi              int rot);
3598*f5c631daSSadaf Ebrahimi 
3599*f5c631daSSadaf Ebrahimi   // FP complex multiply accumulate [Armv8.3].
3600*f5c631daSSadaf Ebrahimi   void fcmla(const VRegister& vd,
3601*f5c631daSSadaf Ebrahimi              const VRegister& vn,
3602*f5c631daSSadaf Ebrahimi              const VRegister& vm,
3603*f5c631daSSadaf Ebrahimi              int rot);
3604*f5c631daSSadaf Ebrahimi 
3605*f5c631daSSadaf Ebrahimi   // FP complex add [Armv8.3].
3606*f5c631daSSadaf Ebrahimi   void fcadd(const VRegister& vd,
3607*f5c631daSSadaf Ebrahimi              const VRegister& vn,
3608*f5c631daSSadaf Ebrahimi              const VRegister& vm,
3609*f5c631daSSadaf Ebrahimi              int rot);
3610*f5c631daSSadaf Ebrahimi 
3611*f5c631daSSadaf Ebrahimi   // Signed 8-bit integer matrix multiply-accumulate (vector).
3612*f5c631daSSadaf Ebrahimi   void smmla(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3613*f5c631daSSadaf Ebrahimi 
3614*f5c631daSSadaf Ebrahimi   // Unsigned and signed 8-bit integer matrix multiply-accumulate (vector).
3615*f5c631daSSadaf Ebrahimi   void usmmla(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3616*f5c631daSSadaf Ebrahimi 
3617*f5c631daSSadaf Ebrahimi   // Unsigned 8-bit integer matrix multiply-accumulate (vector).
3618*f5c631daSSadaf Ebrahimi   void ummla(const VRegister& vd, const VRegister& vn, const VRegister& vm);
3619*f5c631daSSadaf Ebrahimi 
3620*f5c631daSSadaf Ebrahimi   // Scalable Vector Extensions.
3621*f5c631daSSadaf Ebrahimi 
3622*f5c631daSSadaf Ebrahimi   // Absolute value (predicated).
3623*f5c631daSSadaf Ebrahimi   void abs(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
3624*f5c631daSSadaf Ebrahimi 
3625*f5c631daSSadaf Ebrahimi   // Add vectors (predicated).
3626*f5c631daSSadaf Ebrahimi   void add(const ZRegister& zd,
3627*f5c631daSSadaf Ebrahimi            const PRegisterM& pg,
3628*f5c631daSSadaf Ebrahimi            const ZRegister& zn,
3629*f5c631daSSadaf Ebrahimi            const ZRegister& zm);
3630*f5c631daSSadaf Ebrahimi 
3631*f5c631daSSadaf Ebrahimi   // Add vectors (unpredicated).
3632*f5c631daSSadaf Ebrahimi   void add(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
3633*f5c631daSSadaf Ebrahimi 
3634*f5c631daSSadaf Ebrahimi   // Add immediate (unpredicated).
3635*f5c631daSSadaf Ebrahimi   void add(const ZRegister& zd, const ZRegister& zn, int imm8, int shift = -1);
3636*f5c631daSSadaf Ebrahimi 
3637*f5c631daSSadaf Ebrahimi   // Add multiple of predicate register size to scalar register.
3638*f5c631daSSadaf Ebrahimi   void addpl(const Register& xd, const Register& xn, int imm6);
3639*f5c631daSSadaf Ebrahimi 
3640*f5c631daSSadaf Ebrahimi   // Add multiple of vector register size to scalar register.
3641*f5c631daSSadaf Ebrahimi   void addvl(const Register& xd, const Register& xn, int imm6);
3642*f5c631daSSadaf Ebrahimi 
3643*f5c631daSSadaf Ebrahimi   // Compute vector address.
3644*f5c631daSSadaf Ebrahimi   void adr(const ZRegister& zd, const SVEMemOperand& addr);
3645*f5c631daSSadaf Ebrahimi 
3646*f5c631daSSadaf Ebrahimi   // Bitwise AND predicates.
3647*f5c631daSSadaf Ebrahimi   void and_(const PRegisterWithLaneSize& pd,
3648*f5c631daSSadaf Ebrahimi             const PRegisterZ& pg,
3649*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pn,
3650*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pm);
3651*f5c631daSSadaf Ebrahimi 
3652*f5c631daSSadaf Ebrahimi   // Bitwise AND vectors (predicated).
3653*f5c631daSSadaf Ebrahimi   void and_(const ZRegister& zd,
3654*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
3655*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
3656*f5c631daSSadaf Ebrahimi             const ZRegister& zm);
3657*f5c631daSSadaf Ebrahimi 
3658*f5c631daSSadaf Ebrahimi   // Bitwise AND with immediate (unpredicated).
3659*f5c631daSSadaf Ebrahimi   void and_(const ZRegister& zd, const ZRegister& zn, uint64_t imm);
3660*f5c631daSSadaf Ebrahimi 
3661*f5c631daSSadaf Ebrahimi   // Bitwise AND vectors (unpredicated).
3662*f5c631daSSadaf Ebrahimi   void and_(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
3663*f5c631daSSadaf Ebrahimi 
3664*f5c631daSSadaf Ebrahimi   // Bitwise AND predicates.
3665*f5c631daSSadaf Ebrahimi   void ands(const PRegisterWithLaneSize& pd,
3666*f5c631daSSadaf Ebrahimi             const PRegisterZ& pg,
3667*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pn,
3668*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pm);
3669*f5c631daSSadaf Ebrahimi 
3670*f5c631daSSadaf Ebrahimi   // Bitwise AND reduction to scalar.
3671*f5c631daSSadaf Ebrahimi   void andv(const VRegister& vd, const PRegister& pg, const ZRegister& zn);
3672*f5c631daSSadaf Ebrahimi 
3673*f5c631daSSadaf Ebrahimi   // Arithmetic shift right by immediate (predicated).
3674*f5c631daSSadaf Ebrahimi   void asr(const ZRegister& zd,
3675*f5c631daSSadaf Ebrahimi            const PRegisterM& pg,
3676*f5c631daSSadaf Ebrahimi            const ZRegister& zn,
3677*f5c631daSSadaf Ebrahimi            int shift);
3678*f5c631daSSadaf Ebrahimi 
3679*f5c631daSSadaf Ebrahimi   // Arithmetic shift right by 64-bit wide elements (predicated).
3680*f5c631daSSadaf Ebrahimi   void asr(const ZRegister& zd,
3681*f5c631daSSadaf Ebrahimi            const PRegisterM& pg,
3682*f5c631daSSadaf Ebrahimi            const ZRegister& zn,
3683*f5c631daSSadaf Ebrahimi            const ZRegister& zm);
3684*f5c631daSSadaf Ebrahimi 
3685*f5c631daSSadaf Ebrahimi   // Arithmetic shift right by immediate (unpredicated).
3686*f5c631daSSadaf Ebrahimi   void asr(const ZRegister& zd, const ZRegister& zn, int shift);
3687*f5c631daSSadaf Ebrahimi 
3688*f5c631daSSadaf Ebrahimi   // Arithmetic shift right by 64-bit wide elements (unpredicated).
3689*f5c631daSSadaf Ebrahimi   void asr(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
3690*f5c631daSSadaf Ebrahimi 
3691*f5c631daSSadaf Ebrahimi   // Arithmetic shift right for divide by immediate (predicated).
3692*f5c631daSSadaf Ebrahimi   void asrd(const ZRegister& zd,
3693*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
3694*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
3695*f5c631daSSadaf Ebrahimi             int shift);
3696*f5c631daSSadaf Ebrahimi 
3697*f5c631daSSadaf Ebrahimi   // Reversed arithmetic shift right by vector (predicated).
3698*f5c631daSSadaf Ebrahimi   void asrr(const ZRegister& zd,
3699*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
3700*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
3701*f5c631daSSadaf Ebrahimi             const ZRegister& zm);
3702*f5c631daSSadaf Ebrahimi 
3703*f5c631daSSadaf Ebrahimi   // Bitwise clear predicates.
3704*f5c631daSSadaf Ebrahimi   void bic(const PRegisterWithLaneSize& pd,
3705*f5c631daSSadaf Ebrahimi            const PRegisterZ& pg,
3706*f5c631daSSadaf Ebrahimi            const PRegisterWithLaneSize& pn,
3707*f5c631daSSadaf Ebrahimi            const PRegisterWithLaneSize& pm);
3708*f5c631daSSadaf Ebrahimi 
3709*f5c631daSSadaf Ebrahimi   // Bitwise clear vectors (predicated).
3710*f5c631daSSadaf Ebrahimi   void bic(const ZRegister& zd,
3711*f5c631daSSadaf Ebrahimi            const PRegisterM& pg,
3712*f5c631daSSadaf Ebrahimi            const ZRegister& zn,
3713*f5c631daSSadaf Ebrahimi            const ZRegister& zm);
3714*f5c631daSSadaf Ebrahimi 
3715*f5c631daSSadaf Ebrahimi   // Bitwise clear bits using immediate (unpredicated).
3716*f5c631daSSadaf Ebrahimi   void bic(const ZRegister& zd, const ZRegister& zn, uint64_t imm);
3717*f5c631daSSadaf Ebrahimi 
3718*f5c631daSSadaf Ebrahimi   // Bitwise clear vectors (unpredicated).
3719*f5c631daSSadaf Ebrahimi   void bic(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
3720*f5c631daSSadaf Ebrahimi 
3721*f5c631daSSadaf Ebrahimi   // Bitwise clear predicates.
3722*f5c631daSSadaf Ebrahimi   void bics(const PRegisterWithLaneSize& pd,
3723*f5c631daSSadaf Ebrahimi             const PRegisterZ& pg,
3724*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pn,
3725*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pm);
3726*f5c631daSSadaf Ebrahimi 
3727*f5c631daSSadaf Ebrahimi   // Break after first true condition.
3728*f5c631daSSadaf Ebrahimi   void brka(const PRegisterWithLaneSize& pd,
3729*f5c631daSSadaf Ebrahimi             const PRegister& pg,
3730*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pn);
3731*f5c631daSSadaf Ebrahimi 
3732*f5c631daSSadaf Ebrahimi   // Break after first true condition.
3733*f5c631daSSadaf Ebrahimi   void brkas(const PRegisterWithLaneSize& pd,
3734*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
3735*f5c631daSSadaf Ebrahimi              const PRegisterWithLaneSize& pn);
3736*f5c631daSSadaf Ebrahimi 
3737*f5c631daSSadaf Ebrahimi   // Break before first true condition.
3738*f5c631daSSadaf Ebrahimi   void brkb(const PRegisterWithLaneSize& pd,
3739*f5c631daSSadaf Ebrahimi             const PRegister& pg,
3740*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pn);
3741*f5c631daSSadaf Ebrahimi 
3742*f5c631daSSadaf Ebrahimi   // Break before first true condition.
3743*f5c631daSSadaf Ebrahimi   void brkbs(const PRegisterWithLaneSize& pd,
3744*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
3745*f5c631daSSadaf Ebrahimi              const PRegisterWithLaneSize& pn);
3746*f5c631daSSadaf Ebrahimi 
3747*f5c631daSSadaf Ebrahimi   // Propagate break to next partition.
3748*f5c631daSSadaf Ebrahimi   void brkn(const PRegisterWithLaneSize& pd,
3749*f5c631daSSadaf Ebrahimi             const PRegisterZ& pg,
3750*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pn,
3751*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pm);
3752*f5c631daSSadaf Ebrahimi 
3753*f5c631daSSadaf Ebrahimi   // Propagate break to next partition.
3754*f5c631daSSadaf Ebrahimi   void brkns(const PRegisterWithLaneSize& pd,
3755*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
3756*f5c631daSSadaf Ebrahimi              const PRegisterWithLaneSize& pn,
3757*f5c631daSSadaf Ebrahimi              const PRegisterWithLaneSize& pm);
3758*f5c631daSSadaf Ebrahimi 
3759*f5c631daSSadaf Ebrahimi   // Break after first true condition, propagating from previous partition.
3760*f5c631daSSadaf Ebrahimi   void brkpa(const PRegisterWithLaneSize& pd,
3761*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
3762*f5c631daSSadaf Ebrahimi              const PRegisterWithLaneSize& pn,
3763*f5c631daSSadaf Ebrahimi              const PRegisterWithLaneSize& pm);
3764*f5c631daSSadaf Ebrahimi 
3765*f5c631daSSadaf Ebrahimi   // Break after first true condition, propagating from previous partition.
3766*f5c631daSSadaf Ebrahimi   void brkpas(const PRegisterWithLaneSize& pd,
3767*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
3768*f5c631daSSadaf Ebrahimi               const PRegisterWithLaneSize& pn,
3769*f5c631daSSadaf Ebrahimi               const PRegisterWithLaneSize& pm);
3770*f5c631daSSadaf Ebrahimi 
3771*f5c631daSSadaf Ebrahimi   // Break before first true condition, propagating from previous partition.
3772*f5c631daSSadaf Ebrahimi   void brkpb(const PRegisterWithLaneSize& pd,
3773*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
3774*f5c631daSSadaf Ebrahimi              const PRegisterWithLaneSize& pn,
3775*f5c631daSSadaf Ebrahimi              const PRegisterWithLaneSize& pm);
3776*f5c631daSSadaf Ebrahimi 
3777*f5c631daSSadaf Ebrahimi   // Break before first true condition, propagating from previous partition.
3778*f5c631daSSadaf Ebrahimi   void brkpbs(const PRegisterWithLaneSize& pd,
3779*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
3780*f5c631daSSadaf Ebrahimi               const PRegisterWithLaneSize& pn,
3781*f5c631daSSadaf Ebrahimi               const PRegisterWithLaneSize& pm);
3782*f5c631daSSadaf Ebrahimi 
3783*f5c631daSSadaf Ebrahimi   // Conditionally extract element after last to general-purpose register.
3784*f5c631daSSadaf Ebrahimi   void clasta(const Register& rd,
3785*f5c631daSSadaf Ebrahimi               const PRegister& pg,
3786*f5c631daSSadaf Ebrahimi               const Register& rn,
3787*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
3788*f5c631daSSadaf Ebrahimi 
3789*f5c631daSSadaf Ebrahimi   // Conditionally extract element after last to SIMD&FP scalar register.
3790*f5c631daSSadaf Ebrahimi   void clasta(const VRegister& vd,
3791*f5c631daSSadaf Ebrahimi               const PRegister& pg,
3792*f5c631daSSadaf Ebrahimi               const VRegister& vn,
3793*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
3794*f5c631daSSadaf Ebrahimi 
3795*f5c631daSSadaf Ebrahimi   // Conditionally extract element after last to vector register.
3796*f5c631daSSadaf Ebrahimi   void clasta(const ZRegister& zd,
3797*f5c631daSSadaf Ebrahimi               const PRegister& pg,
3798*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
3799*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
3800*f5c631daSSadaf Ebrahimi 
3801*f5c631daSSadaf Ebrahimi   // Conditionally extract last element to general-purpose register.
3802*f5c631daSSadaf Ebrahimi   void clastb(const Register& rd,
3803*f5c631daSSadaf Ebrahimi               const PRegister& pg,
3804*f5c631daSSadaf Ebrahimi               const Register& rn,
3805*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
3806*f5c631daSSadaf Ebrahimi 
3807*f5c631daSSadaf Ebrahimi   // Conditionally extract last element to SIMD&FP scalar register.
3808*f5c631daSSadaf Ebrahimi   void clastb(const VRegister& vd,
3809*f5c631daSSadaf Ebrahimi               const PRegister& pg,
3810*f5c631daSSadaf Ebrahimi               const VRegister& vn,
3811*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
3812*f5c631daSSadaf Ebrahimi 
3813*f5c631daSSadaf Ebrahimi   // Conditionally extract last element to vector register.
3814*f5c631daSSadaf Ebrahimi   void clastb(const ZRegister& zd,
3815*f5c631daSSadaf Ebrahimi               const PRegister& pg,
3816*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
3817*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
3818*f5c631daSSadaf Ebrahimi 
3819*f5c631daSSadaf Ebrahimi   // Count leading sign bits (predicated).
3820*f5c631daSSadaf Ebrahimi   void cls(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
3821*f5c631daSSadaf Ebrahimi 
3822*f5c631daSSadaf Ebrahimi   // Count leading zero bits (predicated).
3823*f5c631daSSadaf Ebrahimi   void clz(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
3824*f5c631daSSadaf Ebrahimi 
3825*f5c631daSSadaf Ebrahimi   void cmp(Condition cond,
3826*f5c631daSSadaf Ebrahimi            const PRegisterWithLaneSize& pd,
3827*f5c631daSSadaf Ebrahimi            const PRegisterZ& pg,
3828*f5c631daSSadaf Ebrahimi            const ZRegister& zn,
3829*f5c631daSSadaf Ebrahimi            const ZRegister& zm);
3830*f5c631daSSadaf Ebrahimi 
3831*f5c631daSSadaf Ebrahimi   // Compare vector to 64-bit wide elements.
3832*f5c631daSSadaf Ebrahimi   void cmpeq(const PRegisterWithLaneSize& pd,
3833*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
3834*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
3835*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
3836*f5c631daSSadaf Ebrahimi 
3837*f5c631daSSadaf Ebrahimi   // Compare vector to immediate.
3838*f5c631daSSadaf Ebrahimi   void cmpeq(const PRegisterWithLaneSize& pd,
3839*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
3840*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
3841*f5c631daSSadaf Ebrahimi              int imm5);
3842*f5c631daSSadaf Ebrahimi 
3843*f5c631daSSadaf Ebrahimi   // Compare vector to 64-bit wide elements.
3844*f5c631daSSadaf Ebrahimi   void cmpge(const PRegisterWithLaneSize& pd,
3845*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
3846*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
3847*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
3848*f5c631daSSadaf Ebrahimi 
3849*f5c631daSSadaf Ebrahimi   // Compare vector to immediate.
3850*f5c631daSSadaf Ebrahimi   void cmpge(const PRegisterWithLaneSize& pd,
3851*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
3852*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
3853*f5c631daSSadaf Ebrahimi              int imm5);
3854*f5c631daSSadaf Ebrahimi 
3855*f5c631daSSadaf Ebrahimi   // Compare vector to 64-bit wide elements.
3856*f5c631daSSadaf Ebrahimi   void cmpgt(const PRegisterWithLaneSize& pd,
3857*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
3858*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
3859*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
3860*f5c631daSSadaf Ebrahimi 
3861*f5c631daSSadaf Ebrahimi   // Compare vector to immediate.
3862*f5c631daSSadaf Ebrahimi   void cmpgt(const PRegisterWithLaneSize& pd,
3863*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
3864*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
3865*f5c631daSSadaf Ebrahimi              int imm5);
3866*f5c631daSSadaf Ebrahimi 
3867*f5c631daSSadaf Ebrahimi   // Compare vector to 64-bit wide elements.
3868*f5c631daSSadaf Ebrahimi   void cmphi(const PRegisterWithLaneSize& pd,
3869*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
3870*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
3871*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
3872*f5c631daSSadaf Ebrahimi 
3873*f5c631daSSadaf Ebrahimi   // Compare vector to immediate.
3874*f5c631daSSadaf Ebrahimi   void cmphi(const PRegisterWithLaneSize& pd,
3875*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
3876*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
3877*f5c631daSSadaf Ebrahimi              unsigned imm7);
3878*f5c631daSSadaf Ebrahimi 
3879*f5c631daSSadaf Ebrahimi   // Compare vector to 64-bit wide elements.
3880*f5c631daSSadaf Ebrahimi   void cmphs(const PRegisterWithLaneSize& pd,
3881*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
3882*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
3883*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
3884*f5c631daSSadaf Ebrahimi 
3885*f5c631daSSadaf Ebrahimi   // Compare vector to immediate.
3886*f5c631daSSadaf Ebrahimi   void cmphs(const PRegisterWithLaneSize& pd,
3887*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
3888*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
3889*f5c631daSSadaf Ebrahimi              unsigned imm7);
3890*f5c631daSSadaf Ebrahimi 
3891*f5c631daSSadaf Ebrahimi   // Compare vector to 64-bit wide elements.
3892*f5c631daSSadaf Ebrahimi   void cmple(const PRegisterWithLaneSize& pd,
3893*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
3894*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
3895*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
3896*f5c631daSSadaf Ebrahimi 
3897*f5c631daSSadaf Ebrahimi   // Compare vector to immediate.
3898*f5c631daSSadaf Ebrahimi   void cmple(const PRegisterWithLaneSize& pd,
3899*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
3900*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
3901*f5c631daSSadaf Ebrahimi              int imm5);
3902*f5c631daSSadaf Ebrahimi 
3903*f5c631daSSadaf Ebrahimi   // Compare vector to 64-bit wide elements.
3904*f5c631daSSadaf Ebrahimi   void cmplo(const PRegisterWithLaneSize& pd,
3905*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
3906*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
3907*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
3908*f5c631daSSadaf Ebrahimi 
3909*f5c631daSSadaf Ebrahimi   // Compare vector to immediate.
3910*f5c631daSSadaf Ebrahimi   void cmplo(const PRegisterWithLaneSize& pd,
3911*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
3912*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
3913*f5c631daSSadaf Ebrahimi              unsigned imm7);
3914*f5c631daSSadaf Ebrahimi 
3915*f5c631daSSadaf Ebrahimi   // Compare vector to 64-bit wide elements.
3916*f5c631daSSadaf Ebrahimi   void cmpls(const PRegisterWithLaneSize& pd,
3917*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
3918*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
3919*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
3920*f5c631daSSadaf Ebrahimi 
3921*f5c631daSSadaf Ebrahimi   // Compare vector to immediate.
3922*f5c631daSSadaf Ebrahimi   void cmpls(const PRegisterWithLaneSize& pd,
3923*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
3924*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
3925*f5c631daSSadaf Ebrahimi              unsigned imm7);
3926*f5c631daSSadaf Ebrahimi 
3927*f5c631daSSadaf Ebrahimi   // Compare vector to 64-bit wide elements.
3928*f5c631daSSadaf Ebrahimi   void cmplt(const PRegisterWithLaneSize& pd,
3929*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
3930*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
3931*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
3932*f5c631daSSadaf Ebrahimi 
3933*f5c631daSSadaf Ebrahimi   // Compare vector to immediate.
3934*f5c631daSSadaf Ebrahimi   void cmplt(const PRegisterWithLaneSize& pd,
3935*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
3936*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
3937*f5c631daSSadaf Ebrahimi              int imm5);
3938*f5c631daSSadaf Ebrahimi 
3939*f5c631daSSadaf Ebrahimi   // Compare vector to 64-bit wide elements.
3940*f5c631daSSadaf Ebrahimi   void cmpne(const PRegisterWithLaneSize& pd,
3941*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
3942*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
3943*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
3944*f5c631daSSadaf Ebrahimi 
3945*f5c631daSSadaf Ebrahimi   // Compare vector to immediate.
3946*f5c631daSSadaf Ebrahimi   void cmpne(const PRegisterWithLaneSize& pd,
3947*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
3948*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
3949*f5c631daSSadaf Ebrahimi              int imm5);
3950*f5c631daSSadaf Ebrahimi 
3951*f5c631daSSadaf Ebrahimi   // Logically invert boolean condition in vector (predicated).
3952*f5c631daSSadaf Ebrahimi   void cnot(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
3953*f5c631daSSadaf Ebrahimi 
3954*f5c631daSSadaf Ebrahimi   // Count non-zero bits (predicated).
3955*f5c631daSSadaf Ebrahimi   void cnt(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
3956*f5c631daSSadaf Ebrahimi 
3957*f5c631daSSadaf Ebrahimi   // Set scalar to multiple of predicate constraint element count.
3958*f5c631daSSadaf Ebrahimi   void cntb(const Register& rd, int pattern = SVE_ALL, int multiplier = 1);
3959*f5c631daSSadaf Ebrahimi 
3960*f5c631daSSadaf Ebrahimi   // Set scalar to multiple of predicate constraint element count.
3961*f5c631daSSadaf Ebrahimi   void cntd(const Register& rd, int pattern = SVE_ALL, int multiplier = 1);
3962*f5c631daSSadaf Ebrahimi 
3963*f5c631daSSadaf Ebrahimi   // Set scalar to multiple of predicate constraint element count.
3964*f5c631daSSadaf Ebrahimi   void cnth(const Register& rd, int pattern = SVE_ALL, int multiplier = 1);
3965*f5c631daSSadaf Ebrahimi 
3966*f5c631daSSadaf Ebrahimi   // Set scalar to active predicate element count.
3967*f5c631daSSadaf Ebrahimi   void cntp(const Register& xd,
3968*f5c631daSSadaf Ebrahimi             const PRegister& pg,
3969*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pn);
3970*f5c631daSSadaf Ebrahimi 
3971*f5c631daSSadaf Ebrahimi   // Set scalar to multiple of predicate constraint element count.
3972*f5c631daSSadaf Ebrahimi   void cntw(const Register& rd, int pattern = SVE_ALL, int multiplier = 1);
3973*f5c631daSSadaf Ebrahimi 
3974*f5c631daSSadaf Ebrahimi   // Shuffle active elements of vector to the right and fill with zero.
3975*f5c631daSSadaf Ebrahimi   void compact(const ZRegister& zd, const PRegister& pg, const ZRegister& zn);
3976*f5c631daSSadaf Ebrahimi 
3977*f5c631daSSadaf Ebrahimi   // Copy signed integer immediate to vector elements (predicated).
3978*f5c631daSSadaf Ebrahimi   void cpy(const ZRegister& zd, const PRegister& pg, int imm8, int shift = -1);
3979*f5c631daSSadaf Ebrahimi 
3980*f5c631daSSadaf Ebrahimi   // Copy general-purpose register to vector elements (predicated).
3981*f5c631daSSadaf Ebrahimi   void cpy(const ZRegister& zd, const PRegisterM& pg, const Register& rn);
3982*f5c631daSSadaf Ebrahimi 
3983*f5c631daSSadaf Ebrahimi   // Copy SIMD&FP scalar register to vector elements (predicated).
3984*f5c631daSSadaf Ebrahimi   void cpy(const ZRegister& zd, const PRegisterM& pg, const VRegister& vn);
3985*f5c631daSSadaf Ebrahimi 
3986*f5c631daSSadaf Ebrahimi   // Compare and terminate loop.
3987*f5c631daSSadaf Ebrahimi   void ctermeq(const Register& rn, const Register& rm);
3988*f5c631daSSadaf Ebrahimi 
3989*f5c631daSSadaf Ebrahimi   // Compare and terminate loop.
3990*f5c631daSSadaf Ebrahimi   void ctermne(const Register& rn, const Register& rm);
3991*f5c631daSSadaf Ebrahimi 
3992*f5c631daSSadaf Ebrahimi   // Decrement scalar by multiple of predicate constraint element count.
3993*f5c631daSSadaf Ebrahimi   void decb(const Register& xdn, int pattern = SVE_ALL, int multiplier = 1);
3994*f5c631daSSadaf Ebrahimi 
3995*f5c631daSSadaf Ebrahimi   // Decrement scalar by multiple of predicate constraint element count.
3996*f5c631daSSadaf Ebrahimi   void decd(const Register& xdn, int pattern = SVE_ALL, int multiplier = 1);
3997*f5c631daSSadaf Ebrahimi 
3998*f5c631daSSadaf Ebrahimi   // Decrement vector by multiple of predicate constraint element count.
3999*f5c631daSSadaf Ebrahimi   void decd(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1);
4000*f5c631daSSadaf Ebrahimi 
4001*f5c631daSSadaf Ebrahimi   // Decrement scalar by multiple of predicate constraint element count.
4002*f5c631daSSadaf Ebrahimi   void dech(const Register& xdn, int pattern = SVE_ALL, int multiplier = 1);
4003*f5c631daSSadaf Ebrahimi 
4004*f5c631daSSadaf Ebrahimi   // Decrement vector by multiple of predicate constraint element count.
4005*f5c631daSSadaf Ebrahimi   void dech(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1);
4006*f5c631daSSadaf Ebrahimi 
4007*f5c631daSSadaf Ebrahimi   // Decrement scalar by active predicate element count.
4008*f5c631daSSadaf Ebrahimi   void decp(const Register& rdn, const PRegisterWithLaneSize& pg);
4009*f5c631daSSadaf Ebrahimi 
4010*f5c631daSSadaf Ebrahimi   // Decrement vector by active predicate element count.
4011*f5c631daSSadaf Ebrahimi   void decp(const ZRegister& zdn, const PRegister& pg);
4012*f5c631daSSadaf Ebrahimi 
4013*f5c631daSSadaf Ebrahimi   // Decrement scalar by multiple of predicate constraint element count.
4014*f5c631daSSadaf Ebrahimi   void decw(const Register& xdn, int pattern = SVE_ALL, int multiplier = 1);
4015*f5c631daSSadaf Ebrahimi 
4016*f5c631daSSadaf Ebrahimi   // Decrement vector by multiple of predicate constraint element count.
4017*f5c631daSSadaf Ebrahimi   void decw(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1);
4018*f5c631daSSadaf Ebrahimi 
4019*f5c631daSSadaf Ebrahimi   // Broadcast general-purpose register to vector elements (unpredicated).
4020*f5c631daSSadaf Ebrahimi   void dup(const ZRegister& zd, const Register& xn);
4021*f5c631daSSadaf Ebrahimi 
4022*f5c631daSSadaf Ebrahimi   // Broadcast indexed element to vector (unpredicated).
4023*f5c631daSSadaf Ebrahimi   void dup(const ZRegister& zd, const ZRegister& zn, unsigned index);
4024*f5c631daSSadaf Ebrahimi 
4025*f5c631daSSadaf Ebrahimi   // As for movz/movk/movn, if the default shift of -1 is specified to dup, the
4026*f5c631daSSadaf Ebrahimi   // assembler will pick an appropriate immediate and left shift that is
4027*f5c631daSSadaf Ebrahimi   // equivalent to the immediate argument. If an explicit left shift is
4028*f5c631daSSadaf Ebrahimi   // specified (0 or 8), the immediate must be a signed 8-bit integer.
4029*f5c631daSSadaf Ebrahimi 
4030*f5c631daSSadaf Ebrahimi   // Broadcast signed immediate to vector elements (unpredicated).
4031*f5c631daSSadaf Ebrahimi   void dup(const ZRegister& zd, int imm8, int shift = -1);
4032*f5c631daSSadaf Ebrahimi 
4033*f5c631daSSadaf Ebrahimi   // Broadcast logical bitmask immediate to vector (unpredicated).
4034*f5c631daSSadaf Ebrahimi   void dupm(const ZRegister& zd, uint64_t imm);
4035*f5c631daSSadaf Ebrahimi 
4036*f5c631daSSadaf Ebrahimi   // Bitwise exclusive OR with inverted immediate (unpredicated).
4037*f5c631daSSadaf Ebrahimi   void eon(const ZRegister& zd, const ZRegister& zn, uint64_t imm);
4038*f5c631daSSadaf Ebrahimi 
4039*f5c631daSSadaf Ebrahimi   // Bitwise exclusive OR predicates.
4040*f5c631daSSadaf Ebrahimi   void eor(const PRegisterWithLaneSize& pd,
4041*f5c631daSSadaf Ebrahimi            const PRegisterZ& pg,
4042*f5c631daSSadaf Ebrahimi            const PRegisterWithLaneSize& pn,
4043*f5c631daSSadaf Ebrahimi            const PRegisterWithLaneSize& pm);
4044*f5c631daSSadaf Ebrahimi 
4045*f5c631daSSadaf Ebrahimi   // Bitwise exclusive OR vectors (predicated).
4046*f5c631daSSadaf Ebrahimi   void eor(const ZRegister& zd,
4047*f5c631daSSadaf Ebrahimi            const PRegisterM& pg,
4048*f5c631daSSadaf Ebrahimi            const ZRegister& zn,
4049*f5c631daSSadaf Ebrahimi            const ZRegister& zm);
4050*f5c631daSSadaf Ebrahimi 
4051*f5c631daSSadaf Ebrahimi   // Bitwise exclusive OR with immediate (unpredicated).
4052*f5c631daSSadaf Ebrahimi   void eor(const ZRegister& zd, const ZRegister& zn, uint64_t imm);
4053*f5c631daSSadaf Ebrahimi 
4054*f5c631daSSadaf Ebrahimi   // Bitwise exclusive OR vectors (unpredicated).
4055*f5c631daSSadaf Ebrahimi   void eor(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
4056*f5c631daSSadaf Ebrahimi 
4057*f5c631daSSadaf Ebrahimi   // Bitwise exclusive OR predicates.
4058*f5c631daSSadaf Ebrahimi   void eors(const PRegisterWithLaneSize& pd,
4059*f5c631daSSadaf Ebrahimi             const PRegisterZ& pg,
4060*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pn,
4061*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pm);
4062*f5c631daSSadaf Ebrahimi 
4063*f5c631daSSadaf Ebrahimi   // Bitwise XOR reduction to scalar.
4064*f5c631daSSadaf Ebrahimi   void eorv(const VRegister& vd, const PRegister& pg, const ZRegister& zn);
4065*f5c631daSSadaf Ebrahimi 
4066*f5c631daSSadaf Ebrahimi   // Extract vector from pair of vectors.
4067*f5c631daSSadaf Ebrahimi   void ext(const ZRegister& zd,
4068*f5c631daSSadaf Ebrahimi            const ZRegister& zn,
4069*f5c631daSSadaf Ebrahimi            const ZRegister& zm,
4070*f5c631daSSadaf Ebrahimi            unsigned offset);
4071*f5c631daSSadaf Ebrahimi 
4072*f5c631daSSadaf Ebrahimi   // Floating-point absolute difference (predicated).
4073*f5c631daSSadaf Ebrahimi   void fabd(const ZRegister& zd,
4074*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
4075*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
4076*f5c631daSSadaf Ebrahimi             const ZRegister& zm);
4077*f5c631daSSadaf Ebrahimi 
4078*f5c631daSSadaf Ebrahimi   // Floating-point absolute value (predicated).
4079*f5c631daSSadaf Ebrahimi   void fabs(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
4080*f5c631daSSadaf Ebrahimi 
4081*f5c631daSSadaf Ebrahimi   // Floating-point absolute compare vectors.
4082*f5c631daSSadaf Ebrahimi   void facge(const PRegisterWithLaneSize& pd,
4083*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
4084*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
4085*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
4086*f5c631daSSadaf Ebrahimi 
4087*f5c631daSSadaf Ebrahimi   // Floating-point absolute compare vectors.
4088*f5c631daSSadaf Ebrahimi   void facgt(const PRegisterWithLaneSize& pd,
4089*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
4090*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
4091*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
4092*f5c631daSSadaf Ebrahimi 
4093*f5c631daSSadaf Ebrahimi   // Floating-point add immediate (predicated).
4094*f5c631daSSadaf Ebrahimi   void fadd(const ZRegister& zd,
4095*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
4096*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
4097*f5c631daSSadaf Ebrahimi             double imm);
4098*f5c631daSSadaf Ebrahimi 
4099*f5c631daSSadaf Ebrahimi   // Floating-point add vector (predicated).
4100*f5c631daSSadaf Ebrahimi   void fadd(const ZRegister& zd,
4101*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
4102*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
4103*f5c631daSSadaf Ebrahimi             const ZRegister& zm);
4104*f5c631daSSadaf Ebrahimi 
4105*f5c631daSSadaf Ebrahimi   // Floating-point add vector (unpredicated).
4106*f5c631daSSadaf Ebrahimi   void fadd(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
4107*f5c631daSSadaf Ebrahimi 
4108*f5c631daSSadaf Ebrahimi   // Floating-point add strictly-ordered reduction, accumulating in scalar.
4109*f5c631daSSadaf Ebrahimi   void fadda(const VRegister& vd,
4110*f5c631daSSadaf Ebrahimi              const PRegister& pg,
4111*f5c631daSSadaf Ebrahimi              const VRegister& vn,
4112*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
4113*f5c631daSSadaf Ebrahimi 
4114*f5c631daSSadaf Ebrahimi   // Floating-point add recursive reduction to scalar.
4115*f5c631daSSadaf Ebrahimi   void faddv(const VRegister& vd, const PRegister& pg, const ZRegister& zn);
4116*f5c631daSSadaf Ebrahimi 
4117*f5c631daSSadaf Ebrahimi   // Floating-point complex add with rotate (predicated).
4118*f5c631daSSadaf Ebrahimi   void fcadd(const ZRegister& zd,
4119*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
4120*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
4121*f5c631daSSadaf Ebrahimi              const ZRegister& zm,
4122*f5c631daSSadaf Ebrahimi              int rot);
4123*f5c631daSSadaf Ebrahimi 
4124*f5c631daSSadaf Ebrahimi   // Floating-point compare vector with zero.
4125*f5c631daSSadaf Ebrahimi   void fcmeq(const PRegisterWithLaneSize& pd,
4126*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
4127*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
4128*f5c631daSSadaf Ebrahimi              double zero);
4129*f5c631daSSadaf Ebrahimi 
4130*f5c631daSSadaf Ebrahimi   // Floating-point compare vectors.
4131*f5c631daSSadaf Ebrahimi   void fcmeq(const PRegisterWithLaneSize& pd,
4132*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
4133*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
4134*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
4135*f5c631daSSadaf Ebrahimi 
4136*f5c631daSSadaf Ebrahimi   // Floating-point compare vector with zero.
4137*f5c631daSSadaf Ebrahimi   void fcmge(const PRegisterWithLaneSize& pd,
4138*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
4139*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
4140*f5c631daSSadaf Ebrahimi              double zero);
4141*f5c631daSSadaf Ebrahimi 
4142*f5c631daSSadaf Ebrahimi   // Floating-point compare vectors.
4143*f5c631daSSadaf Ebrahimi   void fcmge(const PRegisterWithLaneSize& pd,
4144*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
4145*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
4146*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
4147*f5c631daSSadaf Ebrahimi 
4148*f5c631daSSadaf Ebrahimi   // Floating-point compare vector with zero.
4149*f5c631daSSadaf Ebrahimi   void fcmgt(const PRegisterWithLaneSize& pd,
4150*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
4151*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
4152*f5c631daSSadaf Ebrahimi              double zero);
4153*f5c631daSSadaf Ebrahimi 
4154*f5c631daSSadaf Ebrahimi   // Floating-point compare vectors.
4155*f5c631daSSadaf Ebrahimi   void fcmgt(const PRegisterWithLaneSize& pd,
4156*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
4157*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
4158*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
4159*f5c631daSSadaf Ebrahimi 
4160*f5c631daSSadaf Ebrahimi   // Floating-point complex multiply-add with rotate (predicated).
4161*f5c631daSSadaf Ebrahimi   void fcmla(const ZRegister& zda,
4162*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
4163*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
4164*f5c631daSSadaf Ebrahimi              const ZRegister& zm,
4165*f5c631daSSadaf Ebrahimi              int rot);
4166*f5c631daSSadaf Ebrahimi 
4167*f5c631daSSadaf Ebrahimi   // Floating-point complex multiply-add by indexed values with rotate.
4168*f5c631daSSadaf Ebrahimi   void fcmla(const ZRegister& zda,
4169*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
4170*f5c631daSSadaf Ebrahimi              const ZRegister& zm,
4171*f5c631daSSadaf Ebrahimi              int index,
4172*f5c631daSSadaf Ebrahimi              int rot);
4173*f5c631daSSadaf Ebrahimi 
4174*f5c631daSSadaf Ebrahimi   // Floating-point compare vector with zero.
4175*f5c631daSSadaf Ebrahimi   void fcmle(const PRegisterWithLaneSize& pd,
4176*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
4177*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
4178*f5c631daSSadaf Ebrahimi              double zero);
4179*f5c631daSSadaf Ebrahimi 
4180*f5c631daSSadaf Ebrahimi   // Floating-point compare vector with zero.
4181*f5c631daSSadaf Ebrahimi   void fcmlt(const PRegisterWithLaneSize& pd,
4182*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
4183*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
4184*f5c631daSSadaf Ebrahimi              double zero);
4185*f5c631daSSadaf Ebrahimi 
4186*f5c631daSSadaf Ebrahimi   // Floating-point compare vector with zero.
4187*f5c631daSSadaf Ebrahimi   void fcmne(const PRegisterWithLaneSize& pd,
4188*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
4189*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
4190*f5c631daSSadaf Ebrahimi              double zero);
4191*f5c631daSSadaf Ebrahimi 
4192*f5c631daSSadaf Ebrahimi   // Floating-point compare vectors.
4193*f5c631daSSadaf Ebrahimi   void fcmne(const PRegisterWithLaneSize& pd,
4194*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
4195*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
4196*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
4197*f5c631daSSadaf Ebrahimi 
4198*f5c631daSSadaf Ebrahimi   // Floating-point compare vectors.
4199*f5c631daSSadaf Ebrahimi   void fcmuo(const PRegisterWithLaneSize& pd,
4200*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
4201*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
4202*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
4203*f5c631daSSadaf Ebrahimi 
4204*f5c631daSSadaf Ebrahimi   // Copy floating-point immediate to vector elements (predicated).
4205*f5c631daSSadaf Ebrahimi   void fcpy(const ZRegister& zd, const PRegisterM& pg, double imm);
4206*f5c631daSSadaf Ebrahimi 
4207*f5c631daSSadaf Ebrahimi   // Copy half-precision floating-point immediate to vector elements
4208*f5c631daSSadaf Ebrahimi   // (predicated).
fcpy(const ZRegister & zd,const PRegisterM & pg,Float16 imm)4209*f5c631daSSadaf Ebrahimi   void fcpy(const ZRegister& zd, const PRegisterM& pg, Float16 imm) {
4210*f5c631daSSadaf Ebrahimi     fcpy(zd, pg, FPToDouble(imm, kIgnoreDefaultNaN));
4211*f5c631daSSadaf Ebrahimi   }
4212*f5c631daSSadaf Ebrahimi 
4213*f5c631daSSadaf Ebrahimi   // Floating-point convert precision (predicated).
4214*f5c631daSSadaf Ebrahimi   void fcvt(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
4215*f5c631daSSadaf Ebrahimi 
4216*f5c631daSSadaf Ebrahimi   // Floating-point convert to signed integer, rounding toward zero
4217*f5c631daSSadaf Ebrahimi   // (predicated).
4218*f5c631daSSadaf Ebrahimi   void fcvtzs(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
4219*f5c631daSSadaf Ebrahimi 
4220*f5c631daSSadaf Ebrahimi   // Floating-point convert to unsigned integer, rounding toward zero
4221*f5c631daSSadaf Ebrahimi   // (predicated).
4222*f5c631daSSadaf Ebrahimi   void fcvtzu(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
4223*f5c631daSSadaf Ebrahimi 
4224*f5c631daSSadaf Ebrahimi   // Floating-point divide by vector (predicated).
4225*f5c631daSSadaf Ebrahimi   void fdiv(const ZRegister& zd,
4226*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
4227*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
4228*f5c631daSSadaf Ebrahimi             const ZRegister& zm);
4229*f5c631daSSadaf Ebrahimi 
4230*f5c631daSSadaf Ebrahimi   // Floating-point reversed divide by vector (predicated).
4231*f5c631daSSadaf Ebrahimi   void fdivr(const ZRegister& zd,
4232*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
4233*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
4234*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
4235*f5c631daSSadaf Ebrahimi 
4236*f5c631daSSadaf Ebrahimi   // Broadcast floating-point immediate to vector elements.
4237*f5c631daSSadaf Ebrahimi   void fdup(const ZRegister& zd, double imm);
4238*f5c631daSSadaf Ebrahimi 
4239*f5c631daSSadaf Ebrahimi   // Broadcast half-precision floating-point immediate to vector elements.
fdup(const ZRegister & zd,Float16 imm)4240*f5c631daSSadaf Ebrahimi   void fdup(const ZRegister& zd, Float16 imm) {
4241*f5c631daSSadaf Ebrahimi     fdup(zd, FPToDouble(imm, kIgnoreDefaultNaN));
4242*f5c631daSSadaf Ebrahimi   }
4243*f5c631daSSadaf Ebrahimi 
4244*f5c631daSSadaf Ebrahimi   // Floating-point exponential accelerator.
4245*f5c631daSSadaf Ebrahimi   void fexpa(const ZRegister& zd, const ZRegister& zn);
4246*f5c631daSSadaf Ebrahimi 
4247*f5c631daSSadaf Ebrahimi   // Floating-point fused multiply-add vectors (predicated), writing
4248*f5c631daSSadaf Ebrahimi   // multiplicand [Zdn = Za + Zdn * Zm].
4249*f5c631daSSadaf Ebrahimi   void fmad(const ZRegister& zdn,
4250*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
4251*f5c631daSSadaf Ebrahimi             const ZRegister& zm,
4252*f5c631daSSadaf Ebrahimi             const ZRegister& za);
4253*f5c631daSSadaf Ebrahimi 
4254*f5c631daSSadaf Ebrahimi   // Floating-point maximum with immediate (predicated).
4255*f5c631daSSadaf Ebrahimi   void fmax(const ZRegister& zd,
4256*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
4257*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
4258*f5c631daSSadaf Ebrahimi             double imm);
4259*f5c631daSSadaf Ebrahimi 
4260*f5c631daSSadaf Ebrahimi   // Floating-point maximum (predicated).
4261*f5c631daSSadaf Ebrahimi   void fmax(const ZRegister& zd,
4262*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
4263*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
4264*f5c631daSSadaf Ebrahimi             const ZRegister& zm);
4265*f5c631daSSadaf Ebrahimi 
4266*f5c631daSSadaf Ebrahimi   // Floating-point maximum number with immediate (predicated).
4267*f5c631daSSadaf Ebrahimi   void fmaxnm(const ZRegister& zd,
4268*f5c631daSSadaf Ebrahimi               const PRegisterM& pg,
4269*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
4270*f5c631daSSadaf Ebrahimi               double imm);
4271*f5c631daSSadaf Ebrahimi 
4272*f5c631daSSadaf Ebrahimi   // Floating-point maximum number (predicated).
4273*f5c631daSSadaf Ebrahimi   void fmaxnm(const ZRegister& zd,
4274*f5c631daSSadaf Ebrahimi               const PRegisterM& pg,
4275*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
4276*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
4277*f5c631daSSadaf Ebrahimi 
4278*f5c631daSSadaf Ebrahimi   // Floating-point maximum number recursive reduction to scalar.
4279*f5c631daSSadaf Ebrahimi   void fmaxnmv(const VRegister& vd, const PRegister& pg, const ZRegister& zn);
4280*f5c631daSSadaf Ebrahimi 
4281*f5c631daSSadaf Ebrahimi   // Floating-point maximum recursive reduction to scalar.
4282*f5c631daSSadaf Ebrahimi   void fmaxv(const VRegister& vd, const PRegister& pg, const ZRegister& zn);
4283*f5c631daSSadaf Ebrahimi 
4284*f5c631daSSadaf Ebrahimi   // Floating-point minimum with immediate (predicated).
4285*f5c631daSSadaf Ebrahimi   void fmin(const ZRegister& zd,
4286*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
4287*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
4288*f5c631daSSadaf Ebrahimi             double imm);
4289*f5c631daSSadaf Ebrahimi 
4290*f5c631daSSadaf Ebrahimi   // Floating-point minimum (predicated).
4291*f5c631daSSadaf Ebrahimi   void fmin(const ZRegister& zd,
4292*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
4293*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
4294*f5c631daSSadaf Ebrahimi             const ZRegister& zm);
4295*f5c631daSSadaf Ebrahimi 
4296*f5c631daSSadaf Ebrahimi   // Floating-point minimum number with immediate (predicated).
4297*f5c631daSSadaf Ebrahimi   void fminnm(const ZRegister& zd,
4298*f5c631daSSadaf Ebrahimi               const PRegisterM& pg,
4299*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
4300*f5c631daSSadaf Ebrahimi               double imm);
4301*f5c631daSSadaf Ebrahimi 
4302*f5c631daSSadaf Ebrahimi   // Floating-point minimum number (predicated).
4303*f5c631daSSadaf Ebrahimi   void fminnm(const ZRegister& zd,
4304*f5c631daSSadaf Ebrahimi               const PRegisterM& pg,
4305*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
4306*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
4307*f5c631daSSadaf Ebrahimi 
4308*f5c631daSSadaf Ebrahimi   // Floating-point minimum number recursive reduction to scalar.
4309*f5c631daSSadaf Ebrahimi   void fminnmv(const VRegister& vd, const PRegister& pg, const ZRegister& zn);
4310*f5c631daSSadaf Ebrahimi 
4311*f5c631daSSadaf Ebrahimi   // Floating-point minimum recursive reduction to scalar.
4312*f5c631daSSadaf Ebrahimi   void fminv(const VRegister& vd, const PRegister& pg, const ZRegister& zn);
4313*f5c631daSSadaf Ebrahimi 
4314*f5c631daSSadaf Ebrahimi   // Floating-point fused multiply-add vectors (predicated), writing addend
4315*f5c631daSSadaf Ebrahimi   // [Zda = Zda + Zn * Zm].
4316*f5c631daSSadaf Ebrahimi   void fmla(const ZRegister& zda,
4317*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
4318*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
4319*f5c631daSSadaf Ebrahimi             const ZRegister& zm);
4320*f5c631daSSadaf Ebrahimi 
4321*f5c631daSSadaf Ebrahimi   // Floating-point fused multiply-add by indexed elements
4322*f5c631daSSadaf Ebrahimi   // (Zda = Zda + Zn * Zm[indexed]).
4323*f5c631daSSadaf Ebrahimi   void fmla(const ZRegister& zda,
4324*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
4325*f5c631daSSadaf Ebrahimi             const ZRegister& zm,
4326*f5c631daSSadaf Ebrahimi             int index);
4327*f5c631daSSadaf Ebrahimi 
4328*f5c631daSSadaf Ebrahimi   // Floating-point fused multiply-subtract vectors (predicated), writing
4329*f5c631daSSadaf Ebrahimi   // addend [Zda = Zda + -Zn * Zm].
4330*f5c631daSSadaf Ebrahimi   void fmls(const ZRegister& zda,
4331*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
4332*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
4333*f5c631daSSadaf Ebrahimi             const ZRegister& zm);
4334*f5c631daSSadaf Ebrahimi 
4335*f5c631daSSadaf Ebrahimi   // Floating-point fused multiply-subtract by indexed elements
4336*f5c631daSSadaf Ebrahimi   // (Zda = Zda + -Zn * Zm[indexed]).
4337*f5c631daSSadaf Ebrahimi   void fmls(const ZRegister& zda,
4338*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
4339*f5c631daSSadaf Ebrahimi             const ZRegister& zm,
4340*f5c631daSSadaf Ebrahimi             int index);
4341*f5c631daSSadaf Ebrahimi 
4342*f5c631daSSadaf Ebrahimi   // Move 8-bit floating-point immediate to vector elements (unpredicated).
4343*f5c631daSSadaf Ebrahimi   void fmov(const ZRegister& zd, double imm);
4344*f5c631daSSadaf Ebrahimi 
4345*f5c631daSSadaf Ebrahimi   // Move 8-bit floating-point immediate to vector elements (predicated).
4346*f5c631daSSadaf Ebrahimi   void fmov(const ZRegister& zd, const PRegisterM& pg, double imm);
4347*f5c631daSSadaf Ebrahimi 
4348*f5c631daSSadaf Ebrahimi   // Floating-point fused multiply-subtract vectors (predicated), writing
4349*f5c631daSSadaf Ebrahimi   // multiplicand [Zdn = Za + -Zdn * Zm].
4350*f5c631daSSadaf Ebrahimi   void fmsb(const ZRegister& zdn,
4351*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
4352*f5c631daSSadaf Ebrahimi             const ZRegister& zm,
4353*f5c631daSSadaf Ebrahimi             const ZRegister& za);
4354*f5c631daSSadaf Ebrahimi 
4355*f5c631daSSadaf Ebrahimi   // Floating-point multiply by immediate (predicated).
4356*f5c631daSSadaf Ebrahimi   void fmul(const ZRegister& zd,
4357*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
4358*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
4359*f5c631daSSadaf Ebrahimi             double imm);
4360*f5c631daSSadaf Ebrahimi 
4361*f5c631daSSadaf Ebrahimi   // Floating-point multiply vectors (predicated).
4362*f5c631daSSadaf Ebrahimi   void fmul(const ZRegister& zd,
4363*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
4364*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
4365*f5c631daSSadaf Ebrahimi             const ZRegister& zm);
4366*f5c631daSSadaf Ebrahimi 
4367*f5c631daSSadaf Ebrahimi   // Floating-point multiply by indexed elements.
4368*f5c631daSSadaf Ebrahimi   void fmul(const ZRegister& zd,
4369*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
4370*f5c631daSSadaf Ebrahimi             const ZRegister& zm,
4371*f5c631daSSadaf Ebrahimi             unsigned index);
4372*f5c631daSSadaf Ebrahimi 
4373*f5c631daSSadaf Ebrahimi   // Floating-point multiply vectors (unpredicated).
4374*f5c631daSSadaf Ebrahimi   void fmul(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
4375*f5c631daSSadaf Ebrahimi 
4376*f5c631daSSadaf Ebrahimi   // Floating-point multiply-extended vectors (predicated).
4377*f5c631daSSadaf Ebrahimi   void fmulx(const ZRegister& zd,
4378*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
4379*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
4380*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
4381*f5c631daSSadaf Ebrahimi 
4382*f5c631daSSadaf Ebrahimi   // Floating-point negate (predicated).
4383*f5c631daSSadaf Ebrahimi   void fneg(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
4384*f5c631daSSadaf Ebrahimi 
4385*f5c631daSSadaf Ebrahimi   // Floating-point negated fused multiply-add vectors (predicated), writing
4386*f5c631daSSadaf Ebrahimi   // multiplicand [Zdn = -Za + -Zdn * Zm].
4387*f5c631daSSadaf Ebrahimi   void fnmad(const ZRegister& zdn,
4388*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
4389*f5c631daSSadaf Ebrahimi              const ZRegister& zm,
4390*f5c631daSSadaf Ebrahimi              const ZRegister& za);
4391*f5c631daSSadaf Ebrahimi 
4392*f5c631daSSadaf Ebrahimi   // Floating-point negated fused multiply-add vectors (predicated), writing
4393*f5c631daSSadaf Ebrahimi   // addend [Zda = -Zda + -Zn * Zm].
4394*f5c631daSSadaf Ebrahimi   void fnmla(const ZRegister& zda,
4395*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
4396*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
4397*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
4398*f5c631daSSadaf Ebrahimi 
4399*f5c631daSSadaf Ebrahimi   // Floating-point negated fused multiply-subtract vectors (predicated),
4400*f5c631daSSadaf Ebrahimi   // writing addend [Zda = -Zda + Zn * Zm].
4401*f5c631daSSadaf Ebrahimi   void fnmls(const ZRegister& zda,
4402*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
4403*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
4404*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
4405*f5c631daSSadaf Ebrahimi 
4406*f5c631daSSadaf Ebrahimi   // Floating-point negated fused multiply-subtract vectors (predicated),
4407*f5c631daSSadaf Ebrahimi   // writing multiplicand [Zdn = -Za + Zdn * Zm].
4408*f5c631daSSadaf Ebrahimi   void fnmsb(const ZRegister& zdn,
4409*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
4410*f5c631daSSadaf Ebrahimi              const ZRegister& zm,
4411*f5c631daSSadaf Ebrahimi              const ZRegister& za);
4412*f5c631daSSadaf Ebrahimi 
4413*f5c631daSSadaf Ebrahimi   // Floating-point reciprocal estimate (unpredicated).
4414*f5c631daSSadaf Ebrahimi   void frecpe(const ZRegister& zd, const ZRegister& zn);
4415*f5c631daSSadaf Ebrahimi 
4416*f5c631daSSadaf Ebrahimi   // Floating-point reciprocal step (unpredicated).
4417*f5c631daSSadaf Ebrahimi   void frecps(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
4418*f5c631daSSadaf Ebrahimi 
4419*f5c631daSSadaf Ebrahimi   // Floating-point reciprocal exponent (predicated).
4420*f5c631daSSadaf Ebrahimi   void frecpx(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
4421*f5c631daSSadaf Ebrahimi 
4422*f5c631daSSadaf Ebrahimi   // Floating-point round to integral value (predicated).
4423*f5c631daSSadaf Ebrahimi   void frinta(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
4424*f5c631daSSadaf Ebrahimi 
4425*f5c631daSSadaf Ebrahimi   // Floating-point round to integral value (predicated).
4426*f5c631daSSadaf Ebrahimi   void frinti(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
4427*f5c631daSSadaf Ebrahimi 
4428*f5c631daSSadaf Ebrahimi   // Floating-point round to integral value (predicated).
4429*f5c631daSSadaf Ebrahimi   void frintm(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
4430*f5c631daSSadaf Ebrahimi 
4431*f5c631daSSadaf Ebrahimi   // Floating-point round to integral value (predicated).
4432*f5c631daSSadaf Ebrahimi   void frintn(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
4433*f5c631daSSadaf Ebrahimi 
4434*f5c631daSSadaf Ebrahimi   // Floating-point round to integral value (predicated).
4435*f5c631daSSadaf Ebrahimi   void frintp(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
4436*f5c631daSSadaf Ebrahimi 
4437*f5c631daSSadaf Ebrahimi   // Floating-point round to integral value (predicated).
4438*f5c631daSSadaf Ebrahimi   void frintx(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
4439*f5c631daSSadaf Ebrahimi 
4440*f5c631daSSadaf Ebrahimi   // Floating-point round to integral value (predicated).
4441*f5c631daSSadaf Ebrahimi   void frintz(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
4442*f5c631daSSadaf Ebrahimi 
4443*f5c631daSSadaf Ebrahimi   // Floating-point reciprocal square root estimate (unpredicated).
4444*f5c631daSSadaf Ebrahimi   void frsqrte(const ZRegister& zd, const ZRegister& zn);
4445*f5c631daSSadaf Ebrahimi 
4446*f5c631daSSadaf Ebrahimi   // Floating-point reciprocal square root step (unpredicated).
4447*f5c631daSSadaf Ebrahimi   void frsqrts(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
4448*f5c631daSSadaf Ebrahimi 
4449*f5c631daSSadaf Ebrahimi   // Floating-point adjust exponent by vector (predicated).
4450*f5c631daSSadaf Ebrahimi   void fscale(const ZRegister& zd,
4451*f5c631daSSadaf Ebrahimi               const PRegisterM& pg,
4452*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
4453*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
4454*f5c631daSSadaf Ebrahimi 
4455*f5c631daSSadaf Ebrahimi   // Floating-point square root (predicated).
4456*f5c631daSSadaf Ebrahimi   void fsqrt(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
4457*f5c631daSSadaf Ebrahimi 
4458*f5c631daSSadaf Ebrahimi   // Floating-point subtract immediate (predicated).
4459*f5c631daSSadaf Ebrahimi   void fsub(const ZRegister& zd,
4460*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
4461*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
4462*f5c631daSSadaf Ebrahimi             double imm);
4463*f5c631daSSadaf Ebrahimi 
4464*f5c631daSSadaf Ebrahimi   // Floating-point subtract vectors (predicated).
4465*f5c631daSSadaf Ebrahimi   void fsub(const ZRegister& zd,
4466*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
4467*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
4468*f5c631daSSadaf Ebrahimi             const ZRegister& zm);
4469*f5c631daSSadaf Ebrahimi 
4470*f5c631daSSadaf Ebrahimi   // Floating-point subtract vectors (unpredicated).
4471*f5c631daSSadaf Ebrahimi   void fsub(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
4472*f5c631daSSadaf Ebrahimi 
4473*f5c631daSSadaf Ebrahimi   // Floating-point reversed subtract from immediate (predicated).
4474*f5c631daSSadaf Ebrahimi   void fsubr(const ZRegister& zd,
4475*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
4476*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
4477*f5c631daSSadaf Ebrahimi              double imm);
4478*f5c631daSSadaf Ebrahimi 
4479*f5c631daSSadaf Ebrahimi   // Floating-point reversed subtract vectors (predicated).
4480*f5c631daSSadaf Ebrahimi   void fsubr(const ZRegister& zd,
4481*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
4482*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
4483*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
4484*f5c631daSSadaf Ebrahimi 
4485*f5c631daSSadaf Ebrahimi   // Floating-point trigonometric multiply-add coefficient.
4486*f5c631daSSadaf Ebrahimi   void ftmad(const ZRegister& zd,
4487*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
4488*f5c631daSSadaf Ebrahimi              const ZRegister& zm,
4489*f5c631daSSadaf Ebrahimi              int imm3);
4490*f5c631daSSadaf Ebrahimi 
4491*f5c631daSSadaf Ebrahimi   // Floating-point trigonometric starting value.
4492*f5c631daSSadaf Ebrahimi   void ftsmul(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
4493*f5c631daSSadaf Ebrahimi 
4494*f5c631daSSadaf Ebrahimi   // Floating-point trigonometric select coefficient.
4495*f5c631daSSadaf Ebrahimi   void ftssel(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
4496*f5c631daSSadaf Ebrahimi 
4497*f5c631daSSadaf Ebrahimi   // Increment scalar by multiple of predicate constraint element count.
4498*f5c631daSSadaf Ebrahimi   void incb(const Register& xdn, int pattern = SVE_ALL, int multiplier = 1);
4499*f5c631daSSadaf Ebrahimi 
4500*f5c631daSSadaf Ebrahimi   // Increment scalar by multiple of predicate constraint element count.
4501*f5c631daSSadaf Ebrahimi   void incd(const Register& xdn, int pattern = SVE_ALL, int multiplier = 1);
4502*f5c631daSSadaf Ebrahimi 
4503*f5c631daSSadaf Ebrahimi   // Increment vector by multiple of predicate constraint element count.
4504*f5c631daSSadaf Ebrahimi   void incd(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1);
4505*f5c631daSSadaf Ebrahimi 
4506*f5c631daSSadaf Ebrahimi   // Increment scalar by multiple of predicate constraint element count.
4507*f5c631daSSadaf Ebrahimi   void inch(const Register& xdn, int pattern = SVE_ALL, int multiplier = 1);
4508*f5c631daSSadaf Ebrahimi 
4509*f5c631daSSadaf Ebrahimi   // Increment vector by multiple of predicate constraint element count.
4510*f5c631daSSadaf Ebrahimi   void inch(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1);
4511*f5c631daSSadaf Ebrahimi 
4512*f5c631daSSadaf Ebrahimi   // Increment scalar by active predicate element count.
4513*f5c631daSSadaf Ebrahimi   void incp(const Register& rdn, const PRegisterWithLaneSize& pg);
4514*f5c631daSSadaf Ebrahimi 
4515*f5c631daSSadaf Ebrahimi   // Increment vector by active predicate element count.
4516*f5c631daSSadaf Ebrahimi   void incp(const ZRegister& zdn, const PRegister& pg);
4517*f5c631daSSadaf Ebrahimi 
4518*f5c631daSSadaf Ebrahimi   // Increment scalar by multiple of predicate constraint element count.
4519*f5c631daSSadaf Ebrahimi   void incw(const Register& xdn, int pattern = SVE_ALL, int multiplier = 1);
4520*f5c631daSSadaf Ebrahimi 
4521*f5c631daSSadaf Ebrahimi   // Increment vector by multiple of predicate constraint element count.
4522*f5c631daSSadaf Ebrahimi   void incw(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1);
4523*f5c631daSSadaf Ebrahimi 
4524*f5c631daSSadaf Ebrahimi   // Create index starting from and incremented by immediate.
4525*f5c631daSSadaf Ebrahimi   void index(const ZRegister& zd, int start, int step);
4526*f5c631daSSadaf Ebrahimi 
4527*f5c631daSSadaf Ebrahimi   // Create index starting from and incremented by general-purpose register.
4528*f5c631daSSadaf Ebrahimi   void index(const ZRegister& zd, const Register& rn, const Register& rm);
4529*f5c631daSSadaf Ebrahimi 
4530*f5c631daSSadaf Ebrahimi   // Create index starting from general-purpose register and incremented by
4531*f5c631daSSadaf Ebrahimi   // immediate.
4532*f5c631daSSadaf Ebrahimi   void index(const ZRegister& zd, const Register& rn, int imm5);
4533*f5c631daSSadaf Ebrahimi 
4534*f5c631daSSadaf Ebrahimi   // Create index starting from immediate and incremented by general-purpose
4535*f5c631daSSadaf Ebrahimi   // register.
4536*f5c631daSSadaf Ebrahimi   void index(const ZRegister& zd, int imm5, const Register& rm);
4537*f5c631daSSadaf Ebrahimi 
4538*f5c631daSSadaf Ebrahimi   // Insert general-purpose register in shifted vector.
4539*f5c631daSSadaf Ebrahimi   void insr(const ZRegister& zdn, const Register& rm);
4540*f5c631daSSadaf Ebrahimi 
4541*f5c631daSSadaf Ebrahimi   // Insert SIMD&FP scalar register in shifted vector.
4542*f5c631daSSadaf Ebrahimi   void insr(const ZRegister& zdn, const VRegister& vm);
4543*f5c631daSSadaf Ebrahimi 
4544*f5c631daSSadaf Ebrahimi   // Extract element after last to general-purpose register.
4545*f5c631daSSadaf Ebrahimi   void lasta(const Register& rd, const PRegister& pg, const ZRegister& zn);
4546*f5c631daSSadaf Ebrahimi 
4547*f5c631daSSadaf Ebrahimi   // Extract element after last to SIMD&FP scalar register.
4548*f5c631daSSadaf Ebrahimi   void lasta(const VRegister& vd, const PRegister& pg, const ZRegister& zn);
4549*f5c631daSSadaf Ebrahimi 
4550*f5c631daSSadaf Ebrahimi   // Extract last element to general-purpose register.
4551*f5c631daSSadaf Ebrahimi   void lastb(const Register& rd, const PRegister& pg, const ZRegister& zn);
4552*f5c631daSSadaf Ebrahimi 
4553*f5c631daSSadaf Ebrahimi   // Extract last element to SIMD&FP scalar register.
4554*f5c631daSSadaf Ebrahimi   void lastb(const VRegister& vd, const PRegister& pg, const ZRegister& zn);
4555*f5c631daSSadaf Ebrahimi 
4556*f5c631daSSadaf Ebrahimi   // Contiguous/gather load bytes to vector.
4557*f5c631daSSadaf Ebrahimi   void ld1b(const ZRegister& zt,
4558*f5c631daSSadaf Ebrahimi             const PRegisterZ& pg,
4559*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
4560*f5c631daSSadaf Ebrahimi 
4561*f5c631daSSadaf Ebrahimi   // Contiguous/gather load halfwords to vector.
4562*f5c631daSSadaf Ebrahimi   void ld1h(const ZRegister& zt,
4563*f5c631daSSadaf Ebrahimi             const PRegisterZ& pg,
4564*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
4565*f5c631daSSadaf Ebrahimi 
4566*f5c631daSSadaf Ebrahimi   // Contiguous/gather load words to vector.
4567*f5c631daSSadaf Ebrahimi   void ld1w(const ZRegister& zt,
4568*f5c631daSSadaf Ebrahimi             const PRegisterZ& pg,
4569*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
4570*f5c631daSSadaf Ebrahimi 
4571*f5c631daSSadaf Ebrahimi   // Contiguous/gather load doublewords to vector.
4572*f5c631daSSadaf Ebrahimi   void ld1d(const ZRegister& zt,
4573*f5c631daSSadaf Ebrahimi             const PRegisterZ& pg,
4574*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
4575*f5c631daSSadaf Ebrahimi 
4576*f5c631daSSadaf Ebrahimi   // TODO: Merge other loads into the SVEMemOperand versions.
4577*f5c631daSSadaf Ebrahimi 
4578*f5c631daSSadaf Ebrahimi   // Load and broadcast unsigned byte to vector.
4579*f5c631daSSadaf Ebrahimi   void ld1rb(const ZRegister& zt,
4580*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
4581*f5c631daSSadaf Ebrahimi              const SVEMemOperand& addr);
4582*f5c631daSSadaf Ebrahimi 
4583*f5c631daSSadaf Ebrahimi   // Load and broadcast unsigned halfword to vector.
4584*f5c631daSSadaf Ebrahimi   void ld1rh(const ZRegister& zt,
4585*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
4586*f5c631daSSadaf Ebrahimi              const SVEMemOperand& addr);
4587*f5c631daSSadaf Ebrahimi 
4588*f5c631daSSadaf Ebrahimi   // Load and broadcast unsigned word to vector.
4589*f5c631daSSadaf Ebrahimi   void ld1rw(const ZRegister& zt,
4590*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
4591*f5c631daSSadaf Ebrahimi              const SVEMemOperand& addr);
4592*f5c631daSSadaf Ebrahimi 
4593*f5c631daSSadaf Ebrahimi   // Load and broadcast doubleword to vector.
4594*f5c631daSSadaf Ebrahimi   void ld1rd(const ZRegister& zt,
4595*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
4596*f5c631daSSadaf Ebrahimi              const SVEMemOperand& addr);
4597*f5c631daSSadaf Ebrahimi 
4598*f5c631daSSadaf Ebrahimi   // Contiguous load and replicate sixteen bytes.
4599*f5c631daSSadaf Ebrahimi   void ld1rqb(const ZRegister& zt,
4600*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4601*f5c631daSSadaf Ebrahimi               const SVEMemOperand& addr);
4602*f5c631daSSadaf Ebrahimi 
4603*f5c631daSSadaf Ebrahimi   // Contiguous load and replicate eight halfwords.
4604*f5c631daSSadaf Ebrahimi   void ld1rqh(const ZRegister& zt,
4605*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4606*f5c631daSSadaf Ebrahimi               const SVEMemOperand& addr);
4607*f5c631daSSadaf Ebrahimi 
4608*f5c631daSSadaf Ebrahimi   // Contiguous load and replicate four words.
4609*f5c631daSSadaf Ebrahimi   void ld1rqw(const ZRegister& zt,
4610*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4611*f5c631daSSadaf Ebrahimi               const SVEMemOperand& addr);
4612*f5c631daSSadaf Ebrahimi 
4613*f5c631daSSadaf Ebrahimi   // Contiguous load and replicate two doublewords.
4614*f5c631daSSadaf Ebrahimi   void ld1rqd(const ZRegister& zt,
4615*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4616*f5c631daSSadaf Ebrahimi               const SVEMemOperand& addr);
4617*f5c631daSSadaf Ebrahimi 
4618*f5c631daSSadaf Ebrahimi   // Contiguous load and replicate thirty-two bytes.
4619*f5c631daSSadaf Ebrahimi   void ld1rob(const ZRegister& zt,
4620*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4621*f5c631daSSadaf Ebrahimi               const SVEMemOperand& addr);
4622*f5c631daSSadaf Ebrahimi 
4623*f5c631daSSadaf Ebrahimi   // Contiguous load and replicate sixteen halfwords.
4624*f5c631daSSadaf Ebrahimi   void ld1roh(const ZRegister& zt,
4625*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4626*f5c631daSSadaf Ebrahimi               const SVEMemOperand& addr);
4627*f5c631daSSadaf Ebrahimi 
4628*f5c631daSSadaf Ebrahimi   // Contiguous load and replicate eight words.
4629*f5c631daSSadaf Ebrahimi   void ld1row(const ZRegister& zt,
4630*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4631*f5c631daSSadaf Ebrahimi               const SVEMemOperand& addr);
4632*f5c631daSSadaf Ebrahimi 
4633*f5c631daSSadaf Ebrahimi   // Contiguous load and replicate four doublewords.
4634*f5c631daSSadaf Ebrahimi   void ld1rod(const ZRegister& zt,
4635*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4636*f5c631daSSadaf Ebrahimi               const SVEMemOperand& addr);
4637*f5c631daSSadaf Ebrahimi 
4638*f5c631daSSadaf Ebrahimi   // Load and broadcast signed byte to vector.
4639*f5c631daSSadaf Ebrahimi   void ld1rsb(const ZRegister& zt,
4640*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4641*f5c631daSSadaf Ebrahimi               const SVEMemOperand& addr);
4642*f5c631daSSadaf Ebrahimi 
4643*f5c631daSSadaf Ebrahimi   // Load and broadcast signed halfword to vector.
4644*f5c631daSSadaf Ebrahimi   void ld1rsh(const ZRegister& zt,
4645*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4646*f5c631daSSadaf Ebrahimi               const SVEMemOperand& addr);
4647*f5c631daSSadaf Ebrahimi 
4648*f5c631daSSadaf Ebrahimi   // Load and broadcast signed word to vector.
4649*f5c631daSSadaf Ebrahimi   void ld1rsw(const ZRegister& zt,
4650*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4651*f5c631daSSadaf Ebrahimi               const SVEMemOperand& addr);
4652*f5c631daSSadaf Ebrahimi 
4653*f5c631daSSadaf Ebrahimi   // Contiguous/gather load signed bytes to vector.
4654*f5c631daSSadaf Ebrahimi   void ld1sb(const ZRegister& zt,
4655*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
4656*f5c631daSSadaf Ebrahimi              const SVEMemOperand& addr);
4657*f5c631daSSadaf Ebrahimi 
4658*f5c631daSSadaf Ebrahimi   // Contiguous/gather load signed halfwords to vector.
4659*f5c631daSSadaf Ebrahimi   void ld1sh(const ZRegister& zt,
4660*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
4661*f5c631daSSadaf Ebrahimi              const SVEMemOperand& addr);
4662*f5c631daSSadaf Ebrahimi 
4663*f5c631daSSadaf Ebrahimi   // Contiguous/gather load signed words to vector.
4664*f5c631daSSadaf Ebrahimi   void ld1sw(const ZRegister& zt,
4665*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
4666*f5c631daSSadaf Ebrahimi              const SVEMemOperand& addr);
4667*f5c631daSSadaf Ebrahimi 
4668*f5c631daSSadaf Ebrahimi   // TODO: Merge other loads into the SVEMemOperand versions.
4669*f5c631daSSadaf Ebrahimi 
4670*f5c631daSSadaf Ebrahimi   // Contiguous load two-byte structures to two vectors.
4671*f5c631daSSadaf Ebrahimi   void ld2b(const ZRegister& zt1,
4672*f5c631daSSadaf Ebrahimi             const ZRegister& zt2,
4673*f5c631daSSadaf Ebrahimi             const PRegisterZ& pg,
4674*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
4675*f5c631daSSadaf Ebrahimi 
4676*f5c631daSSadaf Ebrahimi   // Contiguous load two-halfword structures to two vectors.
4677*f5c631daSSadaf Ebrahimi   void ld2h(const ZRegister& zt1,
4678*f5c631daSSadaf Ebrahimi             const ZRegister& zt2,
4679*f5c631daSSadaf Ebrahimi             const PRegisterZ& pg,
4680*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
4681*f5c631daSSadaf Ebrahimi 
4682*f5c631daSSadaf Ebrahimi   // Contiguous load two-word structures to two vectors.
4683*f5c631daSSadaf Ebrahimi   void ld2w(const ZRegister& zt1,
4684*f5c631daSSadaf Ebrahimi             const ZRegister& zt2,
4685*f5c631daSSadaf Ebrahimi             const PRegisterZ& pg,
4686*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
4687*f5c631daSSadaf Ebrahimi 
4688*f5c631daSSadaf Ebrahimi   // Contiguous load two-doubleword structures to two vectors.
4689*f5c631daSSadaf Ebrahimi   void ld2d(const ZRegister& zt1,
4690*f5c631daSSadaf Ebrahimi             const ZRegister& zt2,
4691*f5c631daSSadaf Ebrahimi             const PRegisterZ& pg,
4692*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
4693*f5c631daSSadaf Ebrahimi 
4694*f5c631daSSadaf Ebrahimi   // Contiguous load three-byte structures to three vectors.
4695*f5c631daSSadaf Ebrahimi   void ld3b(const ZRegister& zt1,
4696*f5c631daSSadaf Ebrahimi             const ZRegister& zt2,
4697*f5c631daSSadaf Ebrahimi             const ZRegister& zt3,
4698*f5c631daSSadaf Ebrahimi             const PRegisterZ& pg,
4699*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
4700*f5c631daSSadaf Ebrahimi 
4701*f5c631daSSadaf Ebrahimi   // Contiguous load three-halfword structures to three vectors.
4702*f5c631daSSadaf Ebrahimi   void ld3h(const ZRegister& zt1,
4703*f5c631daSSadaf Ebrahimi             const ZRegister& zt2,
4704*f5c631daSSadaf Ebrahimi             const ZRegister& zt3,
4705*f5c631daSSadaf Ebrahimi             const PRegisterZ& pg,
4706*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
4707*f5c631daSSadaf Ebrahimi 
4708*f5c631daSSadaf Ebrahimi   // Contiguous load three-word structures to three vectors.
4709*f5c631daSSadaf Ebrahimi   void ld3w(const ZRegister& zt1,
4710*f5c631daSSadaf Ebrahimi             const ZRegister& zt2,
4711*f5c631daSSadaf Ebrahimi             const ZRegister& zt3,
4712*f5c631daSSadaf Ebrahimi             const PRegisterZ& pg,
4713*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
4714*f5c631daSSadaf Ebrahimi 
4715*f5c631daSSadaf Ebrahimi   // Contiguous load three-doubleword structures to three vectors.
4716*f5c631daSSadaf Ebrahimi   void ld3d(const ZRegister& zt1,
4717*f5c631daSSadaf Ebrahimi             const ZRegister& zt2,
4718*f5c631daSSadaf Ebrahimi             const ZRegister& zt3,
4719*f5c631daSSadaf Ebrahimi             const PRegisterZ& pg,
4720*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
4721*f5c631daSSadaf Ebrahimi 
4722*f5c631daSSadaf Ebrahimi   // Contiguous load four-byte structures to four vectors.
4723*f5c631daSSadaf Ebrahimi   void ld4b(const ZRegister& zt1,
4724*f5c631daSSadaf Ebrahimi             const ZRegister& zt2,
4725*f5c631daSSadaf Ebrahimi             const ZRegister& zt3,
4726*f5c631daSSadaf Ebrahimi             const ZRegister& zt4,
4727*f5c631daSSadaf Ebrahimi             const PRegisterZ& pg,
4728*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
4729*f5c631daSSadaf Ebrahimi 
4730*f5c631daSSadaf Ebrahimi   // Contiguous load four-halfword structures to four vectors.
4731*f5c631daSSadaf Ebrahimi   void ld4h(const ZRegister& zt1,
4732*f5c631daSSadaf Ebrahimi             const ZRegister& zt2,
4733*f5c631daSSadaf Ebrahimi             const ZRegister& zt3,
4734*f5c631daSSadaf Ebrahimi             const ZRegister& zt4,
4735*f5c631daSSadaf Ebrahimi             const PRegisterZ& pg,
4736*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
4737*f5c631daSSadaf Ebrahimi 
4738*f5c631daSSadaf Ebrahimi   // Contiguous load four-word structures to four vectors.
4739*f5c631daSSadaf Ebrahimi   void ld4w(const ZRegister& zt1,
4740*f5c631daSSadaf Ebrahimi             const ZRegister& zt2,
4741*f5c631daSSadaf Ebrahimi             const ZRegister& zt3,
4742*f5c631daSSadaf Ebrahimi             const ZRegister& zt4,
4743*f5c631daSSadaf Ebrahimi             const PRegisterZ& pg,
4744*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
4745*f5c631daSSadaf Ebrahimi 
4746*f5c631daSSadaf Ebrahimi   // Contiguous load four-doubleword structures to four vectors.
4747*f5c631daSSadaf Ebrahimi   void ld4d(const ZRegister& zt1,
4748*f5c631daSSadaf Ebrahimi             const ZRegister& zt2,
4749*f5c631daSSadaf Ebrahimi             const ZRegister& zt3,
4750*f5c631daSSadaf Ebrahimi             const ZRegister& zt4,
4751*f5c631daSSadaf Ebrahimi             const PRegisterZ& pg,
4752*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
4753*f5c631daSSadaf Ebrahimi 
4754*f5c631daSSadaf Ebrahimi   // Contiguous load first-fault unsigned bytes to vector.
4755*f5c631daSSadaf Ebrahimi   void ldff1b(const ZRegister& zt,
4756*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4757*f5c631daSSadaf Ebrahimi               const SVEMemOperand& addr);
4758*f5c631daSSadaf Ebrahimi 
4759*f5c631daSSadaf Ebrahimi   // Contiguous load first-fault unsigned halfwords to vector.
4760*f5c631daSSadaf Ebrahimi   void ldff1h(const ZRegister& zt,
4761*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4762*f5c631daSSadaf Ebrahimi               const SVEMemOperand& addr);
4763*f5c631daSSadaf Ebrahimi 
4764*f5c631daSSadaf Ebrahimi   // Contiguous load first-fault unsigned words to vector.
4765*f5c631daSSadaf Ebrahimi   void ldff1w(const ZRegister& zt,
4766*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4767*f5c631daSSadaf Ebrahimi               const SVEMemOperand& addr);
4768*f5c631daSSadaf Ebrahimi 
4769*f5c631daSSadaf Ebrahimi   // Contiguous load first-fault doublewords to vector.
4770*f5c631daSSadaf Ebrahimi   void ldff1d(const ZRegister& zt,
4771*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4772*f5c631daSSadaf Ebrahimi               const SVEMemOperand& addr);
4773*f5c631daSSadaf Ebrahimi 
4774*f5c631daSSadaf Ebrahimi   // Contiguous load first-fault signed bytes to vector.
4775*f5c631daSSadaf Ebrahimi   void ldff1sb(const ZRegister& zt,
4776*f5c631daSSadaf Ebrahimi                const PRegisterZ& pg,
4777*f5c631daSSadaf Ebrahimi                const SVEMemOperand& addr);
4778*f5c631daSSadaf Ebrahimi 
4779*f5c631daSSadaf Ebrahimi   // Contiguous load first-fault signed halfwords to vector.
4780*f5c631daSSadaf Ebrahimi   void ldff1sh(const ZRegister& zt,
4781*f5c631daSSadaf Ebrahimi                const PRegisterZ& pg,
4782*f5c631daSSadaf Ebrahimi                const SVEMemOperand& addr);
4783*f5c631daSSadaf Ebrahimi 
4784*f5c631daSSadaf Ebrahimi   // Contiguous load first-fault signed words to vector.
4785*f5c631daSSadaf Ebrahimi   void ldff1sw(const ZRegister& zt,
4786*f5c631daSSadaf Ebrahimi                const PRegisterZ& pg,
4787*f5c631daSSadaf Ebrahimi                const SVEMemOperand& addr);
4788*f5c631daSSadaf Ebrahimi 
4789*f5c631daSSadaf Ebrahimi   // Gather load first-fault unsigned bytes to vector.
4790*f5c631daSSadaf Ebrahimi   void ldff1b(const ZRegister& zt,
4791*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4792*f5c631daSSadaf Ebrahimi               const Register& xn,
4793*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
4794*f5c631daSSadaf Ebrahimi 
4795*f5c631daSSadaf Ebrahimi   // Gather load first-fault unsigned bytes to vector (immediate index).
4796*f5c631daSSadaf Ebrahimi   void ldff1b(const ZRegister& zt,
4797*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4798*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
4799*f5c631daSSadaf Ebrahimi               int imm5);
4800*f5c631daSSadaf Ebrahimi 
4801*f5c631daSSadaf Ebrahimi   // Gather load first-fault doublewords to vector (vector index).
4802*f5c631daSSadaf Ebrahimi   void ldff1d(const ZRegister& zt,
4803*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4804*f5c631daSSadaf Ebrahimi               const Register& xn,
4805*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
4806*f5c631daSSadaf Ebrahimi 
4807*f5c631daSSadaf Ebrahimi   // Gather load first-fault doublewords to vector (immediate index).
4808*f5c631daSSadaf Ebrahimi   void ldff1d(const ZRegister& zt,
4809*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4810*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
4811*f5c631daSSadaf Ebrahimi               int imm5);
4812*f5c631daSSadaf Ebrahimi 
4813*f5c631daSSadaf Ebrahimi   // Gather load first-fault unsigned halfwords to vector (vector index).
4814*f5c631daSSadaf Ebrahimi   void ldff1h(const ZRegister& zt,
4815*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4816*f5c631daSSadaf Ebrahimi               const Register& xn,
4817*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
4818*f5c631daSSadaf Ebrahimi 
4819*f5c631daSSadaf Ebrahimi   // Gather load first-fault unsigned halfwords to vector (immediate index).
4820*f5c631daSSadaf Ebrahimi   void ldff1h(const ZRegister& zt,
4821*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4822*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
4823*f5c631daSSadaf Ebrahimi               int imm5);
4824*f5c631daSSadaf Ebrahimi 
4825*f5c631daSSadaf Ebrahimi   // Gather load first-fault signed bytes to vector (vector index).
4826*f5c631daSSadaf Ebrahimi   void ldff1sb(const ZRegister& zt,
4827*f5c631daSSadaf Ebrahimi                const PRegisterZ& pg,
4828*f5c631daSSadaf Ebrahimi                const Register& xn,
4829*f5c631daSSadaf Ebrahimi                const ZRegister& zm);
4830*f5c631daSSadaf Ebrahimi 
4831*f5c631daSSadaf Ebrahimi   // Gather load first-fault signed bytes to vector (immediate index).
4832*f5c631daSSadaf Ebrahimi   void ldff1sb(const ZRegister& zt,
4833*f5c631daSSadaf Ebrahimi                const PRegisterZ& pg,
4834*f5c631daSSadaf Ebrahimi                const ZRegister& zn,
4835*f5c631daSSadaf Ebrahimi                int imm5);
4836*f5c631daSSadaf Ebrahimi 
4837*f5c631daSSadaf Ebrahimi   // Gather load first-fault signed halfwords to vector (vector index).
4838*f5c631daSSadaf Ebrahimi   void ldff1sh(const ZRegister& zt,
4839*f5c631daSSadaf Ebrahimi                const PRegisterZ& pg,
4840*f5c631daSSadaf Ebrahimi                const Register& xn,
4841*f5c631daSSadaf Ebrahimi                const ZRegister& zm);
4842*f5c631daSSadaf Ebrahimi 
4843*f5c631daSSadaf Ebrahimi   // Gather load first-fault signed halfwords to vector (immediate index).
4844*f5c631daSSadaf Ebrahimi   void ldff1sh(const ZRegister& zt,
4845*f5c631daSSadaf Ebrahimi                const PRegisterZ& pg,
4846*f5c631daSSadaf Ebrahimi                const ZRegister& zn,
4847*f5c631daSSadaf Ebrahimi                int imm5);
4848*f5c631daSSadaf Ebrahimi 
4849*f5c631daSSadaf Ebrahimi   // Gather load first-fault signed words to vector (vector index).
4850*f5c631daSSadaf Ebrahimi   void ldff1sw(const ZRegister& zt,
4851*f5c631daSSadaf Ebrahimi                const PRegisterZ& pg,
4852*f5c631daSSadaf Ebrahimi                const Register& xn,
4853*f5c631daSSadaf Ebrahimi                const ZRegister& zm);
4854*f5c631daSSadaf Ebrahimi 
4855*f5c631daSSadaf Ebrahimi   // Gather load first-fault signed words to vector (immediate index).
4856*f5c631daSSadaf Ebrahimi   void ldff1sw(const ZRegister& zt,
4857*f5c631daSSadaf Ebrahimi                const PRegisterZ& pg,
4858*f5c631daSSadaf Ebrahimi                const ZRegister& zn,
4859*f5c631daSSadaf Ebrahimi                int imm5);
4860*f5c631daSSadaf Ebrahimi 
4861*f5c631daSSadaf Ebrahimi   // Gather load first-fault unsigned words to vector (vector index).
4862*f5c631daSSadaf Ebrahimi   void ldff1w(const ZRegister& zt,
4863*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4864*f5c631daSSadaf Ebrahimi               const Register& xn,
4865*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
4866*f5c631daSSadaf Ebrahimi 
4867*f5c631daSSadaf Ebrahimi   // Gather load first-fault unsigned words to vector (immediate index).
4868*f5c631daSSadaf Ebrahimi   void ldff1w(const ZRegister& zt,
4869*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4870*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
4871*f5c631daSSadaf Ebrahimi               int imm5);
4872*f5c631daSSadaf Ebrahimi 
4873*f5c631daSSadaf Ebrahimi   // Contiguous load non-fault unsigned bytes to vector (immediate index).
4874*f5c631daSSadaf Ebrahimi   void ldnf1b(const ZRegister& zt,
4875*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4876*f5c631daSSadaf Ebrahimi               const SVEMemOperand& addr);
4877*f5c631daSSadaf Ebrahimi 
4878*f5c631daSSadaf Ebrahimi   // Contiguous load non-fault doublewords to vector (immediate index).
4879*f5c631daSSadaf Ebrahimi   void ldnf1d(const ZRegister& zt,
4880*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4881*f5c631daSSadaf Ebrahimi               const SVEMemOperand& addr);
4882*f5c631daSSadaf Ebrahimi 
4883*f5c631daSSadaf Ebrahimi   // Contiguous load non-fault unsigned halfwords to vector (immediate
4884*f5c631daSSadaf Ebrahimi   // index).
4885*f5c631daSSadaf Ebrahimi   void ldnf1h(const ZRegister& zt,
4886*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4887*f5c631daSSadaf Ebrahimi               const SVEMemOperand& addr);
4888*f5c631daSSadaf Ebrahimi 
4889*f5c631daSSadaf Ebrahimi   // Contiguous load non-fault signed bytes to vector (immediate index).
4890*f5c631daSSadaf Ebrahimi   void ldnf1sb(const ZRegister& zt,
4891*f5c631daSSadaf Ebrahimi                const PRegisterZ& pg,
4892*f5c631daSSadaf Ebrahimi                const SVEMemOperand& addr);
4893*f5c631daSSadaf Ebrahimi 
4894*f5c631daSSadaf Ebrahimi   // Contiguous load non-fault signed halfwords to vector (immediate index).
4895*f5c631daSSadaf Ebrahimi   void ldnf1sh(const ZRegister& zt,
4896*f5c631daSSadaf Ebrahimi                const PRegisterZ& pg,
4897*f5c631daSSadaf Ebrahimi                const SVEMemOperand& addr);
4898*f5c631daSSadaf Ebrahimi 
4899*f5c631daSSadaf Ebrahimi   // Contiguous load non-fault signed words to vector (immediate index).
4900*f5c631daSSadaf Ebrahimi   void ldnf1sw(const ZRegister& zt,
4901*f5c631daSSadaf Ebrahimi                const PRegisterZ& pg,
4902*f5c631daSSadaf Ebrahimi                const SVEMemOperand& addr);
4903*f5c631daSSadaf Ebrahimi 
4904*f5c631daSSadaf Ebrahimi   // Contiguous load non-fault unsigned words to vector (immediate index).
4905*f5c631daSSadaf Ebrahimi   void ldnf1w(const ZRegister& zt,
4906*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4907*f5c631daSSadaf Ebrahimi               const SVEMemOperand& addr);
4908*f5c631daSSadaf Ebrahimi 
4909*f5c631daSSadaf Ebrahimi   // Contiguous load non-temporal bytes to vector.
4910*f5c631daSSadaf Ebrahimi   void ldnt1b(const ZRegister& zt,
4911*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4912*f5c631daSSadaf Ebrahimi               const SVEMemOperand& addr);
4913*f5c631daSSadaf Ebrahimi 
4914*f5c631daSSadaf Ebrahimi   // Contiguous load non-temporal halfwords to vector.
4915*f5c631daSSadaf Ebrahimi   void ldnt1h(const ZRegister& zt,
4916*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4917*f5c631daSSadaf Ebrahimi               const SVEMemOperand& addr);
4918*f5c631daSSadaf Ebrahimi 
4919*f5c631daSSadaf Ebrahimi   // Contiguous load non-temporal words to vector.
4920*f5c631daSSadaf Ebrahimi   void ldnt1w(const ZRegister& zt,
4921*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4922*f5c631daSSadaf Ebrahimi               const SVEMemOperand& addr);
4923*f5c631daSSadaf Ebrahimi 
4924*f5c631daSSadaf Ebrahimi   // Contiguous load non-temporal doublewords to vector.
4925*f5c631daSSadaf Ebrahimi   void ldnt1d(const ZRegister& zt,
4926*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
4927*f5c631daSSadaf Ebrahimi               const SVEMemOperand& addr);
4928*f5c631daSSadaf Ebrahimi 
4929*f5c631daSSadaf Ebrahimi   // Load SVE predicate/vector register.
4930*f5c631daSSadaf Ebrahimi   void ldr(const CPURegister& rt, const SVEMemOperand& addr);
4931*f5c631daSSadaf Ebrahimi 
4932*f5c631daSSadaf Ebrahimi   // Logical shift left by immediate (predicated).
4933*f5c631daSSadaf Ebrahimi   void lsl(const ZRegister& zd,
4934*f5c631daSSadaf Ebrahimi            const PRegisterM& pg,
4935*f5c631daSSadaf Ebrahimi            const ZRegister& zn,
4936*f5c631daSSadaf Ebrahimi            int shift);
4937*f5c631daSSadaf Ebrahimi 
4938*f5c631daSSadaf Ebrahimi   // Logical shift left by 64-bit wide elements (predicated).
4939*f5c631daSSadaf Ebrahimi   void lsl(const ZRegister& zd,
4940*f5c631daSSadaf Ebrahimi            const PRegisterM& pg,
4941*f5c631daSSadaf Ebrahimi            const ZRegister& zn,
4942*f5c631daSSadaf Ebrahimi            const ZRegister& zm);
4943*f5c631daSSadaf Ebrahimi 
4944*f5c631daSSadaf Ebrahimi   // Logical shift left by immediate (unpredicated).
4945*f5c631daSSadaf Ebrahimi   void lsl(const ZRegister& zd, const ZRegister& zn, int shift);
4946*f5c631daSSadaf Ebrahimi 
4947*f5c631daSSadaf Ebrahimi   // Logical shift left by 64-bit wide elements (unpredicated).
4948*f5c631daSSadaf Ebrahimi   void lsl(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
4949*f5c631daSSadaf Ebrahimi 
4950*f5c631daSSadaf Ebrahimi   // Reversed logical shift left by vector (predicated).
4951*f5c631daSSadaf Ebrahimi   void lslr(const ZRegister& zd,
4952*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
4953*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
4954*f5c631daSSadaf Ebrahimi             const ZRegister& zm);
4955*f5c631daSSadaf Ebrahimi 
4956*f5c631daSSadaf Ebrahimi   // Logical shift right by immediate (predicated).
4957*f5c631daSSadaf Ebrahimi   void lsr(const ZRegister& zd,
4958*f5c631daSSadaf Ebrahimi            const PRegisterM& pg,
4959*f5c631daSSadaf Ebrahimi            const ZRegister& zn,
4960*f5c631daSSadaf Ebrahimi            int shift);
4961*f5c631daSSadaf Ebrahimi 
4962*f5c631daSSadaf Ebrahimi   // Logical shift right by 64-bit wide elements (predicated).
4963*f5c631daSSadaf Ebrahimi   void lsr(const ZRegister& zd,
4964*f5c631daSSadaf Ebrahimi            const PRegisterM& pg,
4965*f5c631daSSadaf Ebrahimi            const ZRegister& zn,
4966*f5c631daSSadaf Ebrahimi            const ZRegister& zm);
4967*f5c631daSSadaf Ebrahimi 
4968*f5c631daSSadaf Ebrahimi   // Logical shift right by immediate (unpredicated).
4969*f5c631daSSadaf Ebrahimi   void lsr(const ZRegister& zd, const ZRegister& zn, int shift);
4970*f5c631daSSadaf Ebrahimi 
4971*f5c631daSSadaf Ebrahimi   // Logical shift right by 64-bit wide elements (unpredicated).
4972*f5c631daSSadaf Ebrahimi   void lsr(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
4973*f5c631daSSadaf Ebrahimi 
4974*f5c631daSSadaf Ebrahimi   // Reversed logical shift right by vector (predicated).
4975*f5c631daSSadaf Ebrahimi   void lsrr(const ZRegister& zd,
4976*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
4977*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
4978*f5c631daSSadaf Ebrahimi             const ZRegister& zm);
4979*f5c631daSSadaf Ebrahimi 
4980*f5c631daSSadaf Ebrahimi   // Bitwise invert predicate.
4981*f5c631daSSadaf Ebrahimi   void not_(const PRegisterWithLaneSize& pd,
4982*f5c631daSSadaf Ebrahimi             const PRegisterZ& pg,
4983*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pn);
4984*f5c631daSSadaf Ebrahimi 
4985*f5c631daSSadaf Ebrahimi   // Bitwise invert predicate, setting the condition flags.
4986*f5c631daSSadaf Ebrahimi   void nots(const PRegisterWithLaneSize& pd,
4987*f5c631daSSadaf Ebrahimi             const PRegisterZ& pg,
4988*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pn);
4989*f5c631daSSadaf Ebrahimi 
4990*f5c631daSSadaf Ebrahimi   // Multiply-add vectors (predicated), writing multiplicand
4991*f5c631daSSadaf Ebrahimi   // [Zdn = Za + Zdn * Zm].
4992*f5c631daSSadaf Ebrahimi   void mad(const ZRegister& zdn,
4993*f5c631daSSadaf Ebrahimi            const PRegisterM& pg,
4994*f5c631daSSadaf Ebrahimi            const ZRegister& zm,
4995*f5c631daSSadaf Ebrahimi            const ZRegister& za);
4996*f5c631daSSadaf Ebrahimi 
4997*f5c631daSSadaf Ebrahimi   // Multiply-add vectors (predicated), writing addend
4998*f5c631daSSadaf Ebrahimi   // [Zda = Zda + Zn * Zm].
4999*f5c631daSSadaf Ebrahimi   void mla(const ZRegister& zda,
5000*f5c631daSSadaf Ebrahimi            const PRegisterM& pg,
5001*f5c631daSSadaf Ebrahimi            const ZRegister& zn,
5002*f5c631daSSadaf Ebrahimi            const ZRegister& zm);
5003*f5c631daSSadaf Ebrahimi 
5004*f5c631daSSadaf Ebrahimi   // Multiply-subtract vectors (predicated), writing addend
5005*f5c631daSSadaf Ebrahimi   // [Zda = Zda - Zn * Zm].
5006*f5c631daSSadaf Ebrahimi   void mls(const ZRegister& zda,
5007*f5c631daSSadaf Ebrahimi            const PRegisterM& pg,
5008*f5c631daSSadaf Ebrahimi            const ZRegister& zn,
5009*f5c631daSSadaf Ebrahimi            const ZRegister& zm);
5010*f5c631daSSadaf Ebrahimi 
5011*f5c631daSSadaf Ebrahimi   // Move predicates (unpredicated)
5012*f5c631daSSadaf Ebrahimi   void mov(const PRegister& pd, const PRegister& pn);
5013*f5c631daSSadaf Ebrahimi 
5014*f5c631daSSadaf Ebrahimi   // Move predicates (merging)
5015*f5c631daSSadaf Ebrahimi   void mov(const PRegisterWithLaneSize& pd,
5016*f5c631daSSadaf Ebrahimi            const PRegisterM& pg,
5017*f5c631daSSadaf Ebrahimi            const PRegisterWithLaneSize& pn);
5018*f5c631daSSadaf Ebrahimi 
5019*f5c631daSSadaf Ebrahimi   // Move predicates (zeroing)
5020*f5c631daSSadaf Ebrahimi   void mov(const PRegisterWithLaneSize& pd,
5021*f5c631daSSadaf Ebrahimi            const PRegisterZ& pg,
5022*f5c631daSSadaf Ebrahimi            const PRegisterWithLaneSize& pn);
5023*f5c631daSSadaf Ebrahimi 
5024*f5c631daSSadaf Ebrahimi   // Move general-purpose register to vector elements (unpredicated)
5025*f5c631daSSadaf Ebrahimi   void mov(const ZRegister& zd, const Register& xn);
5026*f5c631daSSadaf Ebrahimi 
5027*f5c631daSSadaf Ebrahimi   // Move SIMD&FP scalar register to vector elements (unpredicated)
5028*f5c631daSSadaf Ebrahimi   void mov(const ZRegister& zd, const VRegister& vn);
5029*f5c631daSSadaf Ebrahimi 
5030*f5c631daSSadaf Ebrahimi   // Move vector register (unpredicated)
5031*f5c631daSSadaf Ebrahimi   void mov(const ZRegister& zd, const ZRegister& zn);
5032*f5c631daSSadaf Ebrahimi 
5033*f5c631daSSadaf Ebrahimi   // Move indexed element to vector elements (unpredicated)
5034*f5c631daSSadaf Ebrahimi   void mov(const ZRegister& zd, const ZRegister& zn, unsigned index);
5035*f5c631daSSadaf Ebrahimi 
5036*f5c631daSSadaf Ebrahimi   // Move general-purpose register to vector elements (predicated)
5037*f5c631daSSadaf Ebrahimi   void mov(const ZRegister& zd, const PRegisterM& pg, const Register& rn);
5038*f5c631daSSadaf Ebrahimi 
5039*f5c631daSSadaf Ebrahimi   // Move SIMD&FP scalar register to vector elements (predicated)
5040*f5c631daSSadaf Ebrahimi   void mov(const ZRegister& zd, const PRegisterM& pg, const VRegister& vn);
5041*f5c631daSSadaf Ebrahimi 
5042*f5c631daSSadaf Ebrahimi   // Move vector elements (predicated)
5043*f5c631daSSadaf Ebrahimi   void mov(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
5044*f5c631daSSadaf Ebrahimi 
5045*f5c631daSSadaf Ebrahimi   // Move signed integer immediate to vector elements (predicated)
5046*f5c631daSSadaf Ebrahimi   void mov(const ZRegister& zd, const PRegister& pg, int imm8, int shift = -1);
5047*f5c631daSSadaf Ebrahimi 
5048*f5c631daSSadaf Ebrahimi   // Move signed immediate to vector elements (unpredicated).
5049*f5c631daSSadaf Ebrahimi   void mov(const ZRegister& zd, int imm8, int shift);
5050*f5c631daSSadaf Ebrahimi 
5051*f5c631daSSadaf Ebrahimi   // Move logical bitmask immediate to vector (unpredicated).
5052*f5c631daSSadaf Ebrahimi   void mov(const ZRegister& zd, uint64_t imm);
5053*f5c631daSSadaf Ebrahimi 
5054*f5c631daSSadaf Ebrahimi   // Move predicate (unpredicated), setting the condition flags
5055*f5c631daSSadaf Ebrahimi   void movs(const PRegister& pd, const PRegister& pn);
5056*f5c631daSSadaf Ebrahimi 
5057*f5c631daSSadaf Ebrahimi   // Move predicates (zeroing), setting the condition flags
5058*f5c631daSSadaf Ebrahimi   void movs(const PRegisterWithLaneSize& pd,
5059*f5c631daSSadaf Ebrahimi             const PRegisterZ& pg,
5060*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pn);
5061*f5c631daSSadaf Ebrahimi 
5062*f5c631daSSadaf Ebrahimi   // Move prefix (predicated).
5063*f5c631daSSadaf Ebrahimi   void movprfx(const ZRegister& zd, const PRegister& pg, const ZRegister& zn);
5064*f5c631daSSadaf Ebrahimi 
5065*f5c631daSSadaf Ebrahimi   // Move prefix (unpredicated).
5066*f5c631daSSadaf Ebrahimi   void movprfx(const ZRegister& zd, const ZRegister& zn);
5067*f5c631daSSadaf Ebrahimi 
5068*f5c631daSSadaf Ebrahimi   // Multiply-subtract vectors (predicated), writing multiplicand
5069*f5c631daSSadaf Ebrahimi   // [Zdn = Za - Zdn * Zm].
5070*f5c631daSSadaf Ebrahimi   void msb(const ZRegister& zdn,
5071*f5c631daSSadaf Ebrahimi            const PRegisterM& pg,
5072*f5c631daSSadaf Ebrahimi            const ZRegister& zm,
5073*f5c631daSSadaf Ebrahimi            const ZRegister& za);
5074*f5c631daSSadaf Ebrahimi 
5075*f5c631daSSadaf Ebrahimi   // Multiply vectors (predicated).
5076*f5c631daSSadaf Ebrahimi   void mul(const ZRegister& zd,
5077*f5c631daSSadaf Ebrahimi            const PRegisterM& pg,
5078*f5c631daSSadaf Ebrahimi            const ZRegister& zn,
5079*f5c631daSSadaf Ebrahimi            const ZRegister& zm);
5080*f5c631daSSadaf Ebrahimi 
5081*f5c631daSSadaf Ebrahimi   // Multiply by immediate (unpredicated).
5082*f5c631daSSadaf Ebrahimi   void mul(const ZRegister& zd, const ZRegister& zn, int imm8);
5083*f5c631daSSadaf Ebrahimi 
5084*f5c631daSSadaf Ebrahimi   // Bitwise NAND predicates.
5085*f5c631daSSadaf Ebrahimi   void nand(const PRegisterWithLaneSize& pd,
5086*f5c631daSSadaf Ebrahimi             const PRegisterZ& pg,
5087*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pn,
5088*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pm);
5089*f5c631daSSadaf Ebrahimi 
5090*f5c631daSSadaf Ebrahimi   // Bitwise NAND predicates.
5091*f5c631daSSadaf Ebrahimi   void nands(const PRegisterWithLaneSize& pd,
5092*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
5093*f5c631daSSadaf Ebrahimi              const PRegisterWithLaneSize& pn,
5094*f5c631daSSadaf Ebrahimi              const PRegisterWithLaneSize& pm);
5095*f5c631daSSadaf Ebrahimi 
5096*f5c631daSSadaf Ebrahimi   // Negate (predicated).
5097*f5c631daSSadaf Ebrahimi   void neg(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
5098*f5c631daSSadaf Ebrahimi 
5099*f5c631daSSadaf Ebrahimi   // Bitwise NOR predicates.
5100*f5c631daSSadaf Ebrahimi   void nor(const PRegisterWithLaneSize& pd,
5101*f5c631daSSadaf Ebrahimi            const PRegisterZ& pg,
5102*f5c631daSSadaf Ebrahimi            const PRegisterWithLaneSize& pn,
5103*f5c631daSSadaf Ebrahimi            const PRegisterWithLaneSize& pm);
5104*f5c631daSSadaf Ebrahimi 
5105*f5c631daSSadaf Ebrahimi   // Bitwise NOR predicates.
5106*f5c631daSSadaf Ebrahimi   void nors(const PRegisterWithLaneSize& pd,
5107*f5c631daSSadaf Ebrahimi             const PRegisterZ& pg,
5108*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pn,
5109*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pm);
5110*f5c631daSSadaf Ebrahimi 
5111*f5c631daSSadaf Ebrahimi   // Bitwise invert vector (predicated).
5112*f5c631daSSadaf Ebrahimi   void not_(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
5113*f5c631daSSadaf Ebrahimi 
5114*f5c631daSSadaf Ebrahimi   // Bitwise OR inverted predicate.
5115*f5c631daSSadaf Ebrahimi   void orn(const PRegisterWithLaneSize& pd,
5116*f5c631daSSadaf Ebrahimi            const PRegisterZ& pg,
5117*f5c631daSSadaf Ebrahimi            const PRegisterWithLaneSize& pn,
5118*f5c631daSSadaf Ebrahimi            const PRegisterWithLaneSize& pm);
5119*f5c631daSSadaf Ebrahimi 
5120*f5c631daSSadaf Ebrahimi   // Bitwise OR inverted predicate.
5121*f5c631daSSadaf Ebrahimi   void orns(const PRegisterWithLaneSize& pd,
5122*f5c631daSSadaf Ebrahimi             const PRegisterZ& pg,
5123*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pn,
5124*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pm);
5125*f5c631daSSadaf Ebrahimi 
5126*f5c631daSSadaf Ebrahimi   // Bitwise OR with inverted immediate (unpredicated).
5127*f5c631daSSadaf Ebrahimi   void orn(const ZRegister& zd, const ZRegister& zn, uint64_t imm);
5128*f5c631daSSadaf Ebrahimi 
5129*f5c631daSSadaf Ebrahimi   // Bitwise OR predicate.
5130*f5c631daSSadaf Ebrahimi   void orr(const PRegisterWithLaneSize& pd,
5131*f5c631daSSadaf Ebrahimi            const PRegisterZ& pg,
5132*f5c631daSSadaf Ebrahimi            const PRegisterWithLaneSize& pn,
5133*f5c631daSSadaf Ebrahimi            const PRegisterWithLaneSize& pm);
5134*f5c631daSSadaf Ebrahimi 
5135*f5c631daSSadaf Ebrahimi   // Bitwise OR vectors (predicated).
5136*f5c631daSSadaf Ebrahimi   void orr(const ZRegister& zd,
5137*f5c631daSSadaf Ebrahimi            const PRegisterM& pg,
5138*f5c631daSSadaf Ebrahimi            const ZRegister& zn,
5139*f5c631daSSadaf Ebrahimi            const ZRegister& zm);
5140*f5c631daSSadaf Ebrahimi 
5141*f5c631daSSadaf Ebrahimi   // Bitwise OR with immediate (unpredicated).
5142*f5c631daSSadaf Ebrahimi   void orr(const ZRegister& zd, const ZRegister& zn, uint64_t imm);
5143*f5c631daSSadaf Ebrahimi 
5144*f5c631daSSadaf Ebrahimi   // Bitwise OR vectors (unpredicated).
5145*f5c631daSSadaf Ebrahimi   void orr(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
5146*f5c631daSSadaf Ebrahimi 
5147*f5c631daSSadaf Ebrahimi   // Bitwise OR predicate.
5148*f5c631daSSadaf Ebrahimi   void orrs(const PRegisterWithLaneSize& pd,
5149*f5c631daSSadaf Ebrahimi             const PRegisterZ& pg,
5150*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pn,
5151*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pm);
5152*f5c631daSSadaf Ebrahimi 
5153*f5c631daSSadaf Ebrahimi   // Bitwise OR reduction to scalar.
5154*f5c631daSSadaf Ebrahimi   void orv(const VRegister& vd, const PRegister& pg, const ZRegister& zn);
5155*f5c631daSSadaf Ebrahimi 
5156*f5c631daSSadaf Ebrahimi   // Set all predicate elements to false.
5157*f5c631daSSadaf Ebrahimi   void pfalse(const PRegisterWithLaneSize& pd);
5158*f5c631daSSadaf Ebrahimi 
5159*f5c631daSSadaf Ebrahimi   // Set the first active predicate element to true.
5160*f5c631daSSadaf Ebrahimi   void pfirst(const PRegisterWithLaneSize& pd,
5161*f5c631daSSadaf Ebrahimi               const PRegister& pg,
5162*f5c631daSSadaf Ebrahimi               const PRegisterWithLaneSize& pn);
5163*f5c631daSSadaf Ebrahimi 
5164*f5c631daSSadaf Ebrahimi   // Find next active predicate.
5165*f5c631daSSadaf Ebrahimi   void pnext(const PRegisterWithLaneSize& pd,
5166*f5c631daSSadaf Ebrahimi              const PRegister& pg,
5167*f5c631daSSadaf Ebrahimi              const PRegisterWithLaneSize& pn);
5168*f5c631daSSadaf Ebrahimi 
5169*f5c631daSSadaf Ebrahimi   // Prefetch bytes.
5170*f5c631daSSadaf Ebrahimi   void prfb(PrefetchOperation prfop,
5171*f5c631daSSadaf Ebrahimi             const PRegister& pg,
5172*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
5173*f5c631daSSadaf Ebrahimi 
5174*f5c631daSSadaf Ebrahimi   // Prefetch halfwords.
5175*f5c631daSSadaf Ebrahimi   void prfh(PrefetchOperation prfop,
5176*f5c631daSSadaf Ebrahimi             const PRegister& pg,
5177*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
5178*f5c631daSSadaf Ebrahimi 
5179*f5c631daSSadaf Ebrahimi   // Prefetch words.
5180*f5c631daSSadaf Ebrahimi   void prfw(PrefetchOperation prfop,
5181*f5c631daSSadaf Ebrahimi             const PRegister& pg,
5182*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
5183*f5c631daSSadaf Ebrahimi 
5184*f5c631daSSadaf Ebrahimi   // Prefetch doublewords.
5185*f5c631daSSadaf Ebrahimi   void prfd(PrefetchOperation prfop,
5186*f5c631daSSadaf Ebrahimi             const PRegister& pg,
5187*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
5188*f5c631daSSadaf Ebrahimi 
5189*f5c631daSSadaf Ebrahimi   // Set condition flags for predicate.
5190*f5c631daSSadaf Ebrahimi   void ptest(const PRegister& pg, const PRegisterWithLaneSize& pn);
5191*f5c631daSSadaf Ebrahimi 
5192*f5c631daSSadaf Ebrahimi   // Initialise predicate from named constraint.
5193*f5c631daSSadaf Ebrahimi   void ptrue(const PRegisterWithLaneSize& pd, int pattern = SVE_ALL);
5194*f5c631daSSadaf Ebrahimi 
5195*f5c631daSSadaf Ebrahimi   // Initialise predicate from named constraint.
5196*f5c631daSSadaf Ebrahimi   void ptrues(const PRegisterWithLaneSize& pd, int pattern = SVE_ALL);
5197*f5c631daSSadaf Ebrahimi 
5198*f5c631daSSadaf Ebrahimi   // Unpack and widen half of predicate.
5199*f5c631daSSadaf Ebrahimi   void punpkhi(const PRegisterWithLaneSize& pd,
5200*f5c631daSSadaf Ebrahimi                const PRegisterWithLaneSize& pn);
5201*f5c631daSSadaf Ebrahimi 
5202*f5c631daSSadaf Ebrahimi   // Unpack and widen half of predicate.
5203*f5c631daSSadaf Ebrahimi   void punpklo(const PRegisterWithLaneSize& pd,
5204*f5c631daSSadaf Ebrahimi                const PRegisterWithLaneSize& pn);
5205*f5c631daSSadaf Ebrahimi 
5206*f5c631daSSadaf Ebrahimi   // Reverse bits (predicated).
5207*f5c631daSSadaf Ebrahimi   void rbit(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
5208*f5c631daSSadaf Ebrahimi 
5209*f5c631daSSadaf Ebrahimi   // Read the first-fault register.
5210*f5c631daSSadaf Ebrahimi   void rdffr(const PRegisterWithLaneSize& pd);
5211*f5c631daSSadaf Ebrahimi 
5212*f5c631daSSadaf Ebrahimi   // Return predicate of succesfully loaded elements.
5213*f5c631daSSadaf Ebrahimi   void rdffr(const PRegisterWithLaneSize& pd, const PRegisterZ& pg);
5214*f5c631daSSadaf Ebrahimi 
5215*f5c631daSSadaf Ebrahimi   // Return predicate of succesfully loaded elements.
5216*f5c631daSSadaf Ebrahimi   void rdffrs(const PRegisterWithLaneSize& pd, const PRegisterZ& pg);
5217*f5c631daSSadaf Ebrahimi 
5218*f5c631daSSadaf Ebrahimi   // Read multiple of vector register size to scalar register.
5219*f5c631daSSadaf Ebrahimi   void rdvl(const Register& xd, int imm6);
5220*f5c631daSSadaf Ebrahimi 
5221*f5c631daSSadaf Ebrahimi   // Reverse all elements in a predicate.
5222*f5c631daSSadaf Ebrahimi   void rev(const PRegisterWithLaneSize& pd, const PRegisterWithLaneSize& pn);
5223*f5c631daSSadaf Ebrahimi 
5224*f5c631daSSadaf Ebrahimi   // Reverse all elements in a vector (unpredicated).
5225*f5c631daSSadaf Ebrahimi   void rev(const ZRegister& zd, const ZRegister& zn);
5226*f5c631daSSadaf Ebrahimi 
5227*f5c631daSSadaf Ebrahimi   // Reverse bytes / halfwords / words within elements (predicated).
5228*f5c631daSSadaf Ebrahimi   void revb(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
5229*f5c631daSSadaf Ebrahimi 
5230*f5c631daSSadaf Ebrahimi   // Reverse bytes / halfwords / words within elements (predicated).
5231*f5c631daSSadaf Ebrahimi   void revh(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
5232*f5c631daSSadaf Ebrahimi 
5233*f5c631daSSadaf Ebrahimi   // Reverse bytes / halfwords / words within elements (predicated).
5234*f5c631daSSadaf Ebrahimi   void revw(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
5235*f5c631daSSadaf Ebrahimi 
5236*f5c631daSSadaf Ebrahimi   // Signed absolute difference (predicated).
5237*f5c631daSSadaf Ebrahimi   void sabd(const ZRegister& zd,
5238*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
5239*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
5240*f5c631daSSadaf Ebrahimi             const ZRegister& zm);
5241*f5c631daSSadaf Ebrahimi 
5242*f5c631daSSadaf Ebrahimi   // Signed add reduction to scalar.
5243*f5c631daSSadaf Ebrahimi   void saddv(const VRegister& dd, const PRegister& pg, const ZRegister& zn);
5244*f5c631daSSadaf Ebrahimi 
5245*f5c631daSSadaf Ebrahimi   // Signed integer convert to floating-point (predicated).
5246*f5c631daSSadaf Ebrahimi   void scvtf(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
5247*f5c631daSSadaf Ebrahimi 
5248*f5c631daSSadaf Ebrahimi   // Signed divide (predicated).
5249*f5c631daSSadaf Ebrahimi   void sdiv(const ZRegister& zd,
5250*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
5251*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
5252*f5c631daSSadaf Ebrahimi             const ZRegister& zm);
5253*f5c631daSSadaf Ebrahimi 
5254*f5c631daSSadaf Ebrahimi   // Signed reversed divide (predicated).
5255*f5c631daSSadaf Ebrahimi   void sdivr(const ZRegister& zd,
5256*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
5257*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
5258*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
5259*f5c631daSSadaf Ebrahimi 
5260*f5c631daSSadaf Ebrahimi   // Signed dot product by indexed quadtuplet.
5261*f5c631daSSadaf Ebrahimi   void sdot(const ZRegister& zda,
5262*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
5263*f5c631daSSadaf Ebrahimi             const ZRegister& zm,
5264*f5c631daSSadaf Ebrahimi             int index);
5265*f5c631daSSadaf Ebrahimi 
5266*f5c631daSSadaf Ebrahimi   // Signed dot product.
5267*f5c631daSSadaf Ebrahimi   void sdot(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
5268*f5c631daSSadaf Ebrahimi 
5269*f5c631daSSadaf Ebrahimi   // Conditionally select elements from two predicates.
5270*f5c631daSSadaf Ebrahimi   void sel(const PRegisterWithLaneSize& pd,
5271*f5c631daSSadaf Ebrahimi            const PRegister& pg,
5272*f5c631daSSadaf Ebrahimi            const PRegisterWithLaneSize& pn,
5273*f5c631daSSadaf Ebrahimi            const PRegisterWithLaneSize& pm);
5274*f5c631daSSadaf Ebrahimi 
5275*f5c631daSSadaf Ebrahimi   // Conditionally select elements from two vectors.
5276*f5c631daSSadaf Ebrahimi   void sel(const ZRegister& zd,
5277*f5c631daSSadaf Ebrahimi            const PRegister& pg,
5278*f5c631daSSadaf Ebrahimi            const ZRegister& zn,
5279*f5c631daSSadaf Ebrahimi            const ZRegister& zm);
5280*f5c631daSSadaf Ebrahimi 
5281*f5c631daSSadaf Ebrahimi   // Initialise the first-fault register to all true.
5282*f5c631daSSadaf Ebrahimi   void setffr();
5283*f5c631daSSadaf Ebrahimi 
5284*f5c631daSSadaf Ebrahimi   // Signed maximum vectors (predicated).
5285*f5c631daSSadaf Ebrahimi   void smax(const ZRegister& zd,
5286*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
5287*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
5288*f5c631daSSadaf Ebrahimi             const ZRegister& zm);
5289*f5c631daSSadaf Ebrahimi 
5290*f5c631daSSadaf Ebrahimi   // Signed maximum with immediate (unpredicated).
5291*f5c631daSSadaf Ebrahimi   void smax(const ZRegister& zd, const ZRegister& zn, int imm8);
5292*f5c631daSSadaf Ebrahimi 
5293*f5c631daSSadaf Ebrahimi   // Signed maximum reduction to scalar.
5294*f5c631daSSadaf Ebrahimi   void smaxv(const VRegister& vd, const PRegister& pg, const ZRegister& zn);
5295*f5c631daSSadaf Ebrahimi 
5296*f5c631daSSadaf Ebrahimi   // Signed minimum vectors (predicated).
5297*f5c631daSSadaf Ebrahimi   void smin(const ZRegister& zd,
5298*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
5299*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
5300*f5c631daSSadaf Ebrahimi             const ZRegister& zm);
5301*f5c631daSSadaf Ebrahimi 
5302*f5c631daSSadaf Ebrahimi   // Signed minimum with immediate (unpredicated).
5303*f5c631daSSadaf Ebrahimi   void smin(const ZRegister& zd, const ZRegister& zn, int imm8);
5304*f5c631daSSadaf Ebrahimi 
5305*f5c631daSSadaf Ebrahimi   // Signed minimum reduction to scalar.
5306*f5c631daSSadaf Ebrahimi   void sminv(const VRegister& vd, const PRegister& pg, const ZRegister& zn);
5307*f5c631daSSadaf Ebrahimi 
5308*f5c631daSSadaf Ebrahimi   // Signed multiply returning high half (predicated).
5309*f5c631daSSadaf Ebrahimi   void smulh(const ZRegister& zd,
5310*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
5311*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
5312*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
5313*f5c631daSSadaf Ebrahimi 
5314*f5c631daSSadaf Ebrahimi   // Splice two vectors under predicate control.
5315*f5c631daSSadaf Ebrahimi   void splice(const ZRegister& zd,
5316*f5c631daSSadaf Ebrahimi               const PRegister& pg,
5317*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
5318*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
5319*f5c631daSSadaf Ebrahimi 
5320*f5c631daSSadaf Ebrahimi   // Splice two vectors under predicate control (constructive).
5321*f5c631daSSadaf Ebrahimi   void splice_con(const ZRegister& zd,
5322*f5c631daSSadaf Ebrahimi                   const PRegister& pg,
5323*f5c631daSSadaf Ebrahimi                   const ZRegister& zn,
5324*f5c631daSSadaf Ebrahimi                   const ZRegister& zm);
5325*f5c631daSSadaf Ebrahimi 
5326*f5c631daSSadaf Ebrahimi   // Signed saturating add vectors (unpredicated).
5327*f5c631daSSadaf Ebrahimi   void sqadd(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
5328*f5c631daSSadaf Ebrahimi 
5329*f5c631daSSadaf Ebrahimi   // Signed saturating add immediate (unpredicated).
5330*f5c631daSSadaf Ebrahimi   void sqadd(const ZRegister& zd,
5331*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
5332*f5c631daSSadaf Ebrahimi              int imm8,
5333*f5c631daSSadaf Ebrahimi              int shift = -1);
5334*f5c631daSSadaf Ebrahimi 
5335*f5c631daSSadaf Ebrahimi   // Signed saturating decrement scalar by multiple of 8-bit predicate
5336*f5c631daSSadaf Ebrahimi   // constraint element count.
5337*f5c631daSSadaf Ebrahimi   void sqdecb(const Register& xd,
5338*f5c631daSSadaf Ebrahimi               const Register& wn,
5339*f5c631daSSadaf Ebrahimi               int pattern,
5340*f5c631daSSadaf Ebrahimi               int multiplier);
5341*f5c631daSSadaf Ebrahimi 
5342*f5c631daSSadaf Ebrahimi   // Signed saturating decrement scalar by multiple of 8-bit predicate
5343*f5c631daSSadaf Ebrahimi   // constraint element count.
5344*f5c631daSSadaf Ebrahimi   void sqdecb(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1);
5345*f5c631daSSadaf Ebrahimi 
5346*f5c631daSSadaf Ebrahimi   // Signed saturating decrement scalar by multiple of 64-bit predicate
5347*f5c631daSSadaf Ebrahimi   // constraint element count.
5348*f5c631daSSadaf Ebrahimi   void sqdecd(const Register& xd,
5349*f5c631daSSadaf Ebrahimi               const Register& wn,
5350*f5c631daSSadaf Ebrahimi               int pattern = SVE_ALL,
5351*f5c631daSSadaf Ebrahimi               int multiplier = 1);
5352*f5c631daSSadaf Ebrahimi 
5353*f5c631daSSadaf Ebrahimi   // Signed saturating decrement scalar by multiple of 64-bit predicate
5354*f5c631daSSadaf Ebrahimi   // constraint element count.
5355*f5c631daSSadaf Ebrahimi   void sqdecd(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1);
5356*f5c631daSSadaf Ebrahimi 
5357*f5c631daSSadaf Ebrahimi   // Signed saturating decrement vector by multiple of 64-bit predicate
5358*f5c631daSSadaf Ebrahimi   // constraint element count.
5359*f5c631daSSadaf Ebrahimi   void sqdecd(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1);
5360*f5c631daSSadaf Ebrahimi 
5361*f5c631daSSadaf Ebrahimi   // Signed saturating decrement scalar by multiple of 16-bit predicate
5362*f5c631daSSadaf Ebrahimi   // constraint element count.
5363*f5c631daSSadaf Ebrahimi   void sqdech(const Register& xd,
5364*f5c631daSSadaf Ebrahimi               const Register& wn,
5365*f5c631daSSadaf Ebrahimi               int pattern = SVE_ALL,
5366*f5c631daSSadaf Ebrahimi               int multiplier = 1);
5367*f5c631daSSadaf Ebrahimi 
5368*f5c631daSSadaf Ebrahimi   // Signed saturating decrement scalar by multiple of 16-bit predicate
5369*f5c631daSSadaf Ebrahimi   // constraint element count.
5370*f5c631daSSadaf Ebrahimi   void sqdech(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1);
5371*f5c631daSSadaf Ebrahimi 
5372*f5c631daSSadaf Ebrahimi   // Signed saturating decrement vector by multiple of 16-bit predicate
5373*f5c631daSSadaf Ebrahimi   // constraint element count.
5374*f5c631daSSadaf Ebrahimi   void sqdech(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1);
5375*f5c631daSSadaf Ebrahimi 
5376*f5c631daSSadaf Ebrahimi   // Signed saturating decrement scalar by active predicate element count.
5377*f5c631daSSadaf Ebrahimi   void sqdecp(const Register& xd,
5378*f5c631daSSadaf Ebrahimi               const PRegisterWithLaneSize& pg,
5379*f5c631daSSadaf Ebrahimi               const Register& wn);
5380*f5c631daSSadaf Ebrahimi 
5381*f5c631daSSadaf Ebrahimi   // Signed saturating decrement scalar by active predicate element count.
5382*f5c631daSSadaf Ebrahimi   void sqdecp(const Register& xdn, const PRegisterWithLaneSize& pg);
5383*f5c631daSSadaf Ebrahimi 
5384*f5c631daSSadaf Ebrahimi   // Signed saturating decrement vector by active predicate element count.
5385*f5c631daSSadaf Ebrahimi   void sqdecp(const ZRegister& zdn, const PRegister& pg);
5386*f5c631daSSadaf Ebrahimi 
5387*f5c631daSSadaf Ebrahimi   // Signed saturating decrement scalar by multiple of 32-bit predicate
5388*f5c631daSSadaf Ebrahimi   // constraint element count.
5389*f5c631daSSadaf Ebrahimi   void sqdecw(const Register& xd,
5390*f5c631daSSadaf Ebrahimi               const Register& wn,
5391*f5c631daSSadaf Ebrahimi               int pattern = SVE_ALL,
5392*f5c631daSSadaf Ebrahimi               int multiplier = 1);
5393*f5c631daSSadaf Ebrahimi 
5394*f5c631daSSadaf Ebrahimi   // Signed saturating decrement scalar by multiple of 32-bit predicate
5395*f5c631daSSadaf Ebrahimi   // constraint element count.
5396*f5c631daSSadaf Ebrahimi   void sqdecw(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1);
5397*f5c631daSSadaf Ebrahimi 
5398*f5c631daSSadaf Ebrahimi   // Signed saturating decrement vector by multiple of 32-bit predicate
5399*f5c631daSSadaf Ebrahimi   // constraint element count.
5400*f5c631daSSadaf Ebrahimi   void sqdecw(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1);
5401*f5c631daSSadaf Ebrahimi 
5402*f5c631daSSadaf Ebrahimi   // Signed saturating increment scalar by multiple of 8-bit predicate
5403*f5c631daSSadaf Ebrahimi   // constraint element count.
5404*f5c631daSSadaf Ebrahimi   void sqincb(const Register& xd,
5405*f5c631daSSadaf Ebrahimi               const Register& wn,
5406*f5c631daSSadaf Ebrahimi               int pattern = SVE_ALL,
5407*f5c631daSSadaf Ebrahimi               int multiplier = 1);
5408*f5c631daSSadaf Ebrahimi 
5409*f5c631daSSadaf Ebrahimi   // Signed saturating increment scalar by multiple of 8-bit predicate
5410*f5c631daSSadaf Ebrahimi   // constraint element count.
5411*f5c631daSSadaf Ebrahimi   void sqincb(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1);
5412*f5c631daSSadaf Ebrahimi 
5413*f5c631daSSadaf Ebrahimi   // Signed saturating increment scalar by multiple of 64-bit predicate
5414*f5c631daSSadaf Ebrahimi   // constraint element count.
5415*f5c631daSSadaf Ebrahimi   void sqincd(const Register& xd,
5416*f5c631daSSadaf Ebrahimi               const Register& wn,
5417*f5c631daSSadaf Ebrahimi               int pattern,
5418*f5c631daSSadaf Ebrahimi               int multiplier);
5419*f5c631daSSadaf Ebrahimi 
5420*f5c631daSSadaf Ebrahimi   // Signed saturating increment scalar by multiple of 64-bit predicate
5421*f5c631daSSadaf Ebrahimi   // constraint element count.
5422*f5c631daSSadaf Ebrahimi   void sqincd(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1);
5423*f5c631daSSadaf Ebrahimi 
5424*f5c631daSSadaf Ebrahimi   // Signed saturating increment vector by multiple of 64-bit predicate
5425*f5c631daSSadaf Ebrahimi   // constraint element count.
5426*f5c631daSSadaf Ebrahimi   void sqincd(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1);
5427*f5c631daSSadaf Ebrahimi 
5428*f5c631daSSadaf Ebrahimi   // Signed saturating increment scalar by multiple of 16-bit predicate
5429*f5c631daSSadaf Ebrahimi   // constraint element count.
5430*f5c631daSSadaf Ebrahimi   void sqinch(const Register& xd,
5431*f5c631daSSadaf Ebrahimi               const Register& wn,
5432*f5c631daSSadaf Ebrahimi               int pattern = SVE_ALL,
5433*f5c631daSSadaf Ebrahimi               int multiplier = 1);
5434*f5c631daSSadaf Ebrahimi 
5435*f5c631daSSadaf Ebrahimi   // Signed saturating increment scalar by multiple of 16-bit predicate
5436*f5c631daSSadaf Ebrahimi   // constraint element count.
5437*f5c631daSSadaf Ebrahimi   void sqinch(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1);
5438*f5c631daSSadaf Ebrahimi 
5439*f5c631daSSadaf Ebrahimi   // Signed saturating increment vector by multiple of 16-bit predicate
5440*f5c631daSSadaf Ebrahimi   // constraint element count.
5441*f5c631daSSadaf Ebrahimi   void sqinch(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1);
5442*f5c631daSSadaf Ebrahimi 
5443*f5c631daSSadaf Ebrahimi   // Signed saturating increment scalar by active predicate element count.
5444*f5c631daSSadaf Ebrahimi   void sqincp(const Register& xd,
5445*f5c631daSSadaf Ebrahimi               const PRegisterWithLaneSize& pg,
5446*f5c631daSSadaf Ebrahimi               const Register& wn);
5447*f5c631daSSadaf Ebrahimi 
5448*f5c631daSSadaf Ebrahimi   // Signed saturating increment scalar by active predicate element count.
5449*f5c631daSSadaf Ebrahimi   void sqincp(const Register& xdn, const PRegisterWithLaneSize& pg);
5450*f5c631daSSadaf Ebrahimi 
5451*f5c631daSSadaf Ebrahimi   // Signed saturating increment vector by active predicate element count.
5452*f5c631daSSadaf Ebrahimi   void sqincp(const ZRegister& zdn, const PRegister& pg);
5453*f5c631daSSadaf Ebrahimi 
5454*f5c631daSSadaf Ebrahimi   // Signed saturating increment scalar by multiple of 32-bit predicate
5455*f5c631daSSadaf Ebrahimi   // constraint element count.
5456*f5c631daSSadaf Ebrahimi   void sqincw(const Register& xd,
5457*f5c631daSSadaf Ebrahimi               const Register& wn,
5458*f5c631daSSadaf Ebrahimi               int pattern = SVE_ALL,
5459*f5c631daSSadaf Ebrahimi               int multiplier = 1);
5460*f5c631daSSadaf Ebrahimi 
5461*f5c631daSSadaf Ebrahimi   // Signed saturating increment scalar by multiple of 32-bit predicate
5462*f5c631daSSadaf Ebrahimi   // constraint element count.
5463*f5c631daSSadaf Ebrahimi   void sqincw(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1);
5464*f5c631daSSadaf Ebrahimi 
5465*f5c631daSSadaf Ebrahimi   // Signed saturating increment vector by multiple of 32-bit predicate
5466*f5c631daSSadaf Ebrahimi   // constraint element count.
5467*f5c631daSSadaf Ebrahimi   void sqincw(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1);
5468*f5c631daSSadaf Ebrahimi 
5469*f5c631daSSadaf Ebrahimi   // Signed saturating subtract vectors (unpredicated).
5470*f5c631daSSadaf Ebrahimi   void sqsub(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
5471*f5c631daSSadaf Ebrahimi 
5472*f5c631daSSadaf Ebrahimi   // Signed saturating subtract immediate (unpredicated).
5473*f5c631daSSadaf Ebrahimi   void sqsub(const ZRegister& zd,
5474*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
5475*f5c631daSSadaf Ebrahimi              int imm8,
5476*f5c631daSSadaf Ebrahimi              int shift = -1);
5477*f5c631daSSadaf Ebrahimi 
5478*f5c631daSSadaf Ebrahimi   // Contiguous/scatter store bytes from vector.
5479*f5c631daSSadaf Ebrahimi   void st1b(const ZRegister& zt,
5480*f5c631daSSadaf Ebrahimi             const PRegister& pg,
5481*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
5482*f5c631daSSadaf Ebrahimi 
5483*f5c631daSSadaf Ebrahimi   // Contiguous/scatter store halfwords from vector.
5484*f5c631daSSadaf Ebrahimi   void st1h(const ZRegister& zt,
5485*f5c631daSSadaf Ebrahimi             const PRegister& pg,
5486*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
5487*f5c631daSSadaf Ebrahimi 
5488*f5c631daSSadaf Ebrahimi   // Contiguous/scatter store words from vector.
5489*f5c631daSSadaf Ebrahimi   void st1w(const ZRegister& zt,
5490*f5c631daSSadaf Ebrahimi             const PRegister& pg,
5491*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
5492*f5c631daSSadaf Ebrahimi 
5493*f5c631daSSadaf Ebrahimi   // Contiguous/scatter store doublewords from vector.
5494*f5c631daSSadaf Ebrahimi   void st1d(const ZRegister& zt,
5495*f5c631daSSadaf Ebrahimi             const PRegister& pg,
5496*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
5497*f5c631daSSadaf Ebrahimi 
5498*f5c631daSSadaf Ebrahimi   // Contiguous store two-byte structures from two vectors.
5499*f5c631daSSadaf Ebrahimi   void st2b(const ZRegister& zt1,
5500*f5c631daSSadaf Ebrahimi             const ZRegister& zt2,
5501*f5c631daSSadaf Ebrahimi             const PRegister& pg,
5502*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
5503*f5c631daSSadaf Ebrahimi 
5504*f5c631daSSadaf Ebrahimi   // Contiguous store two-halfword structures from two vectors.
5505*f5c631daSSadaf Ebrahimi   void st2h(const ZRegister& zt1,
5506*f5c631daSSadaf Ebrahimi             const ZRegister& zt2,
5507*f5c631daSSadaf Ebrahimi             const PRegister& pg,
5508*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
5509*f5c631daSSadaf Ebrahimi 
5510*f5c631daSSadaf Ebrahimi   // Contiguous store two-word structures from two vectors.
5511*f5c631daSSadaf Ebrahimi   void st2w(const ZRegister& zt1,
5512*f5c631daSSadaf Ebrahimi             const ZRegister& zt2,
5513*f5c631daSSadaf Ebrahimi             const PRegister& pg,
5514*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
5515*f5c631daSSadaf Ebrahimi 
5516*f5c631daSSadaf Ebrahimi   // Contiguous store two-doubleword structures from two vectors,
5517*f5c631daSSadaf Ebrahimi   void st2d(const ZRegister& zt1,
5518*f5c631daSSadaf Ebrahimi             const ZRegister& zt2,
5519*f5c631daSSadaf Ebrahimi             const PRegister& pg,
5520*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
5521*f5c631daSSadaf Ebrahimi 
5522*f5c631daSSadaf Ebrahimi   // Contiguous store three-byte structures from three vectors.
5523*f5c631daSSadaf Ebrahimi   void st3b(const ZRegister& zt1,
5524*f5c631daSSadaf Ebrahimi             const ZRegister& zt2,
5525*f5c631daSSadaf Ebrahimi             const ZRegister& zt3,
5526*f5c631daSSadaf Ebrahimi             const PRegister& pg,
5527*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
5528*f5c631daSSadaf Ebrahimi 
5529*f5c631daSSadaf Ebrahimi   // Contiguous store three-halfword structures from three vectors.
5530*f5c631daSSadaf Ebrahimi   void st3h(const ZRegister& zt1,
5531*f5c631daSSadaf Ebrahimi             const ZRegister& zt2,
5532*f5c631daSSadaf Ebrahimi             const ZRegister& zt3,
5533*f5c631daSSadaf Ebrahimi             const PRegister& pg,
5534*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
5535*f5c631daSSadaf Ebrahimi 
5536*f5c631daSSadaf Ebrahimi   // Contiguous store three-word structures from three vectors.
5537*f5c631daSSadaf Ebrahimi   void st3w(const ZRegister& zt1,
5538*f5c631daSSadaf Ebrahimi             const ZRegister& zt2,
5539*f5c631daSSadaf Ebrahimi             const ZRegister& zt3,
5540*f5c631daSSadaf Ebrahimi             const PRegister& pg,
5541*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
5542*f5c631daSSadaf Ebrahimi 
5543*f5c631daSSadaf Ebrahimi   // Contiguous store three-doubleword structures from three vectors.
5544*f5c631daSSadaf Ebrahimi   void st3d(const ZRegister& zt1,
5545*f5c631daSSadaf Ebrahimi             const ZRegister& zt2,
5546*f5c631daSSadaf Ebrahimi             const ZRegister& zt3,
5547*f5c631daSSadaf Ebrahimi             const PRegister& pg,
5548*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
5549*f5c631daSSadaf Ebrahimi 
5550*f5c631daSSadaf Ebrahimi   // Contiguous store four-byte structures from four vectors.
5551*f5c631daSSadaf Ebrahimi   void st4b(const ZRegister& zt1,
5552*f5c631daSSadaf Ebrahimi             const ZRegister& zt2,
5553*f5c631daSSadaf Ebrahimi             const ZRegister& zt3,
5554*f5c631daSSadaf Ebrahimi             const ZRegister& zt4,
5555*f5c631daSSadaf Ebrahimi             const PRegister& pg,
5556*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
5557*f5c631daSSadaf Ebrahimi 
5558*f5c631daSSadaf Ebrahimi   // Contiguous store four-halfword structures from four vectors.
5559*f5c631daSSadaf Ebrahimi   void st4h(const ZRegister& zt1,
5560*f5c631daSSadaf Ebrahimi             const ZRegister& zt2,
5561*f5c631daSSadaf Ebrahimi             const ZRegister& zt3,
5562*f5c631daSSadaf Ebrahimi             const ZRegister& zt4,
5563*f5c631daSSadaf Ebrahimi             const PRegister& pg,
5564*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
5565*f5c631daSSadaf Ebrahimi 
5566*f5c631daSSadaf Ebrahimi   // Contiguous store four-word structures from four vectors.
5567*f5c631daSSadaf Ebrahimi   void st4w(const ZRegister& zt1,
5568*f5c631daSSadaf Ebrahimi             const ZRegister& zt2,
5569*f5c631daSSadaf Ebrahimi             const ZRegister& zt3,
5570*f5c631daSSadaf Ebrahimi             const ZRegister& zt4,
5571*f5c631daSSadaf Ebrahimi             const PRegister& pg,
5572*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
5573*f5c631daSSadaf Ebrahimi 
5574*f5c631daSSadaf Ebrahimi   // Contiguous store four-doubleword structures from four vectors.
5575*f5c631daSSadaf Ebrahimi   void st4d(const ZRegister& zt1,
5576*f5c631daSSadaf Ebrahimi             const ZRegister& zt2,
5577*f5c631daSSadaf Ebrahimi             const ZRegister& zt3,
5578*f5c631daSSadaf Ebrahimi             const ZRegister& zt4,
5579*f5c631daSSadaf Ebrahimi             const PRegister& pg,
5580*f5c631daSSadaf Ebrahimi             const SVEMemOperand& addr);
5581*f5c631daSSadaf Ebrahimi 
5582*f5c631daSSadaf Ebrahimi   // Contiguous store non-temporal bytes from vector.
5583*f5c631daSSadaf Ebrahimi   void stnt1b(const ZRegister& zt,
5584*f5c631daSSadaf Ebrahimi               const PRegister& pg,
5585*f5c631daSSadaf Ebrahimi               const SVEMemOperand& addr);
5586*f5c631daSSadaf Ebrahimi 
5587*f5c631daSSadaf Ebrahimi   // Contiguous store non-temporal halfwords from vector.
5588*f5c631daSSadaf Ebrahimi   void stnt1h(const ZRegister& zt,
5589*f5c631daSSadaf Ebrahimi               const PRegister& pg,
5590*f5c631daSSadaf Ebrahimi               const SVEMemOperand& addr);
5591*f5c631daSSadaf Ebrahimi 
5592*f5c631daSSadaf Ebrahimi   // Contiguous store non-temporal words from vector.
5593*f5c631daSSadaf Ebrahimi   void stnt1w(const ZRegister& zt,
5594*f5c631daSSadaf Ebrahimi               const PRegister& pg,
5595*f5c631daSSadaf Ebrahimi               const SVEMemOperand& addr);
5596*f5c631daSSadaf Ebrahimi 
5597*f5c631daSSadaf Ebrahimi   // Contiguous store non-temporal doublewords from vector.
5598*f5c631daSSadaf Ebrahimi   void stnt1d(const ZRegister& zt,
5599*f5c631daSSadaf Ebrahimi               const PRegister& pg,
5600*f5c631daSSadaf Ebrahimi               const SVEMemOperand& addr);
5601*f5c631daSSadaf Ebrahimi 
5602*f5c631daSSadaf Ebrahimi   // Store SVE predicate/vector register.
5603*f5c631daSSadaf Ebrahimi   void str(const CPURegister& rt, const SVEMemOperand& addr);
5604*f5c631daSSadaf Ebrahimi 
5605*f5c631daSSadaf Ebrahimi   // Subtract vectors (predicated).
5606*f5c631daSSadaf Ebrahimi   void sub(const ZRegister& zd,
5607*f5c631daSSadaf Ebrahimi            const PRegisterM& pg,
5608*f5c631daSSadaf Ebrahimi            const ZRegister& zn,
5609*f5c631daSSadaf Ebrahimi            const ZRegister& zm);
5610*f5c631daSSadaf Ebrahimi 
5611*f5c631daSSadaf Ebrahimi   // Subtract vectors (unpredicated).
5612*f5c631daSSadaf Ebrahimi   void sub(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
5613*f5c631daSSadaf Ebrahimi 
5614*f5c631daSSadaf Ebrahimi   // Subtract immediate (unpredicated).
5615*f5c631daSSadaf Ebrahimi   void sub(const ZRegister& zd, const ZRegister& zn, int imm8, int shift = -1);
5616*f5c631daSSadaf Ebrahimi 
5617*f5c631daSSadaf Ebrahimi   // Reversed subtract vectors (predicated).
5618*f5c631daSSadaf Ebrahimi   void subr(const ZRegister& zd,
5619*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
5620*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
5621*f5c631daSSadaf Ebrahimi             const ZRegister& zm);
5622*f5c631daSSadaf Ebrahimi 
5623*f5c631daSSadaf Ebrahimi   // Reversed subtract from immediate (unpredicated).
5624*f5c631daSSadaf Ebrahimi   void subr(const ZRegister& zd, const ZRegister& zn, int imm8, int shift = -1);
5625*f5c631daSSadaf Ebrahimi 
5626*f5c631daSSadaf Ebrahimi   // Signed unpack and extend half of vector.
5627*f5c631daSSadaf Ebrahimi   void sunpkhi(const ZRegister& zd, const ZRegister& zn);
5628*f5c631daSSadaf Ebrahimi 
5629*f5c631daSSadaf Ebrahimi   // Signed unpack and extend half of vector.
5630*f5c631daSSadaf Ebrahimi   void sunpklo(const ZRegister& zd, const ZRegister& zn);
5631*f5c631daSSadaf Ebrahimi 
5632*f5c631daSSadaf Ebrahimi   // Signed byte extend (predicated).
5633*f5c631daSSadaf Ebrahimi   void sxtb(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
5634*f5c631daSSadaf Ebrahimi 
5635*f5c631daSSadaf Ebrahimi   // Signed halfword extend (predicated).
5636*f5c631daSSadaf Ebrahimi   void sxth(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
5637*f5c631daSSadaf Ebrahimi 
5638*f5c631daSSadaf Ebrahimi   // Signed word extend (predicated).
5639*f5c631daSSadaf Ebrahimi   void sxtw(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
5640*f5c631daSSadaf Ebrahimi 
5641*f5c631daSSadaf Ebrahimi   // Programmable table lookup/permute using vector of indices into a
5642*f5c631daSSadaf Ebrahimi   // vector.
5643*f5c631daSSadaf Ebrahimi   void tbl(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
5644*f5c631daSSadaf Ebrahimi 
5645*f5c631daSSadaf Ebrahimi   // Interleave even or odd elements from two predicates.
5646*f5c631daSSadaf Ebrahimi   void trn1(const PRegisterWithLaneSize& pd,
5647*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pn,
5648*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pm);
5649*f5c631daSSadaf Ebrahimi 
5650*f5c631daSSadaf Ebrahimi   // Interleave even or odd elements from two vectors.
5651*f5c631daSSadaf Ebrahimi   void trn1(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
5652*f5c631daSSadaf Ebrahimi 
5653*f5c631daSSadaf Ebrahimi   // Interleave even or odd elements from two predicates.
5654*f5c631daSSadaf Ebrahimi   void trn2(const PRegisterWithLaneSize& pd,
5655*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pn,
5656*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pm);
5657*f5c631daSSadaf Ebrahimi 
5658*f5c631daSSadaf Ebrahimi   // Interleave even or odd elements from two vectors.
5659*f5c631daSSadaf Ebrahimi   void trn2(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
5660*f5c631daSSadaf Ebrahimi 
5661*f5c631daSSadaf Ebrahimi   // Unsigned absolute difference (predicated).
5662*f5c631daSSadaf Ebrahimi   void uabd(const ZRegister& zd,
5663*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
5664*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
5665*f5c631daSSadaf Ebrahimi             const ZRegister& zm);
5666*f5c631daSSadaf Ebrahimi 
5667*f5c631daSSadaf Ebrahimi   // Unsigned add reduction to scalar.
5668*f5c631daSSadaf Ebrahimi   void uaddv(const VRegister& dd, const PRegister& pg, const ZRegister& zn);
5669*f5c631daSSadaf Ebrahimi 
5670*f5c631daSSadaf Ebrahimi   // Unsigned integer convert to floating-point (predicated).
5671*f5c631daSSadaf Ebrahimi   void ucvtf(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
5672*f5c631daSSadaf Ebrahimi 
5673*f5c631daSSadaf Ebrahimi   // Unsigned divide (predicated).
5674*f5c631daSSadaf Ebrahimi   void udiv(const ZRegister& zd,
5675*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
5676*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
5677*f5c631daSSadaf Ebrahimi             const ZRegister& zm);
5678*f5c631daSSadaf Ebrahimi 
5679*f5c631daSSadaf Ebrahimi   // Unsigned reversed divide (predicated).
5680*f5c631daSSadaf Ebrahimi   void udivr(const ZRegister& zd,
5681*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
5682*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
5683*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
5684*f5c631daSSadaf Ebrahimi 
5685*f5c631daSSadaf Ebrahimi   // Unsigned dot product by indexed quadtuplet.
5686*f5c631daSSadaf Ebrahimi   void udot(const ZRegister& zda,
5687*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
5688*f5c631daSSadaf Ebrahimi             const ZRegister& zm,
5689*f5c631daSSadaf Ebrahimi             int index);
5690*f5c631daSSadaf Ebrahimi 
5691*f5c631daSSadaf Ebrahimi   // Unsigned dot product.
5692*f5c631daSSadaf Ebrahimi   void udot(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
5693*f5c631daSSadaf Ebrahimi 
5694*f5c631daSSadaf Ebrahimi   // Unsigned maximum vectors (predicated).
5695*f5c631daSSadaf Ebrahimi   void umax(const ZRegister& zd,
5696*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
5697*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
5698*f5c631daSSadaf Ebrahimi             const ZRegister& zm);
5699*f5c631daSSadaf Ebrahimi 
5700*f5c631daSSadaf Ebrahimi   // Unsigned maximum with immediate (unpredicated).
5701*f5c631daSSadaf Ebrahimi   void umax(const ZRegister& zd, const ZRegister& zn, int imm8);
5702*f5c631daSSadaf Ebrahimi 
5703*f5c631daSSadaf Ebrahimi   // Unsigned maximum reduction to scalar.
5704*f5c631daSSadaf Ebrahimi   void umaxv(const VRegister& vd, const PRegister& pg, const ZRegister& zn);
5705*f5c631daSSadaf Ebrahimi 
5706*f5c631daSSadaf Ebrahimi   // Unsigned minimum vectors (predicated).
5707*f5c631daSSadaf Ebrahimi   void umin(const ZRegister& zd,
5708*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
5709*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
5710*f5c631daSSadaf Ebrahimi             const ZRegister& zm);
5711*f5c631daSSadaf Ebrahimi 
5712*f5c631daSSadaf Ebrahimi   // Unsigned minimum with immediate (unpredicated).
5713*f5c631daSSadaf Ebrahimi   void umin(const ZRegister& zd, const ZRegister& zn, int imm8);
5714*f5c631daSSadaf Ebrahimi 
5715*f5c631daSSadaf Ebrahimi   // Unsigned minimum reduction to scalar.
5716*f5c631daSSadaf Ebrahimi   void uminv(const VRegister& vd, const PRegister& pg, const ZRegister& zn);
5717*f5c631daSSadaf Ebrahimi 
5718*f5c631daSSadaf Ebrahimi   // Unsigned multiply returning high half (predicated).
5719*f5c631daSSadaf Ebrahimi   void umulh(const ZRegister& zd,
5720*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
5721*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
5722*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
5723*f5c631daSSadaf Ebrahimi 
5724*f5c631daSSadaf Ebrahimi   // Unsigned saturating add vectors (unpredicated).
5725*f5c631daSSadaf Ebrahimi   void uqadd(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
5726*f5c631daSSadaf Ebrahimi 
5727*f5c631daSSadaf Ebrahimi   // Unsigned saturating add immediate (unpredicated).
5728*f5c631daSSadaf Ebrahimi   void uqadd(const ZRegister& zd,
5729*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
5730*f5c631daSSadaf Ebrahimi              int imm8,
5731*f5c631daSSadaf Ebrahimi              int shift = -1);
5732*f5c631daSSadaf Ebrahimi 
5733*f5c631daSSadaf Ebrahimi   // Unsigned saturating decrement scalar by multiple of 8-bit predicate
5734*f5c631daSSadaf Ebrahimi   // constraint element count.
5735*f5c631daSSadaf Ebrahimi   void uqdecb(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1);
5736*f5c631daSSadaf Ebrahimi 
5737*f5c631daSSadaf Ebrahimi   // Unsigned saturating decrement scalar by multiple of 64-bit predicate
5738*f5c631daSSadaf Ebrahimi   // constraint element count.
5739*f5c631daSSadaf Ebrahimi   void uqdecd(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1);
5740*f5c631daSSadaf Ebrahimi 
5741*f5c631daSSadaf Ebrahimi   // Unsigned saturating decrement vector by multiple of 64-bit predicate
5742*f5c631daSSadaf Ebrahimi   // constraint element count.
5743*f5c631daSSadaf Ebrahimi   void uqdecd(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1);
5744*f5c631daSSadaf Ebrahimi 
5745*f5c631daSSadaf Ebrahimi   // Unsigned saturating decrement scalar by multiple of 16-bit predicate
5746*f5c631daSSadaf Ebrahimi   // constraint element count.
5747*f5c631daSSadaf Ebrahimi   void uqdech(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1);
5748*f5c631daSSadaf Ebrahimi 
5749*f5c631daSSadaf Ebrahimi   // Unsigned saturating decrement vector by multiple of 16-bit predicate
5750*f5c631daSSadaf Ebrahimi   // constraint element count.
5751*f5c631daSSadaf Ebrahimi   void uqdech(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1);
5752*f5c631daSSadaf Ebrahimi 
5753*f5c631daSSadaf Ebrahimi   // Unsigned saturating decrement scalar by active predicate element count.
5754*f5c631daSSadaf Ebrahimi   void uqdecp(const Register& rdn, const PRegisterWithLaneSize& pg);
5755*f5c631daSSadaf Ebrahimi 
5756*f5c631daSSadaf Ebrahimi   // Unsigned saturating decrement vector by active predicate element count.
5757*f5c631daSSadaf Ebrahimi   void uqdecp(const ZRegister& zdn, const PRegister& pg);
5758*f5c631daSSadaf Ebrahimi 
5759*f5c631daSSadaf Ebrahimi   // Unsigned saturating decrement scalar by multiple of 32-bit predicate
5760*f5c631daSSadaf Ebrahimi   // constraint element count.
5761*f5c631daSSadaf Ebrahimi   void uqdecw(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1);
5762*f5c631daSSadaf Ebrahimi 
5763*f5c631daSSadaf Ebrahimi   // Unsigned saturating decrement vector by multiple of 32-bit predicate
5764*f5c631daSSadaf Ebrahimi   // constraint element count.
5765*f5c631daSSadaf Ebrahimi   void uqdecw(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1);
5766*f5c631daSSadaf Ebrahimi 
5767*f5c631daSSadaf Ebrahimi   // Unsigned saturating increment scalar by multiple of 8-bit predicate
5768*f5c631daSSadaf Ebrahimi   // constraint element count.
5769*f5c631daSSadaf Ebrahimi   void uqincb(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1);
5770*f5c631daSSadaf Ebrahimi 
5771*f5c631daSSadaf Ebrahimi   // Unsigned saturating increment scalar by multiple of 64-bit predicate
5772*f5c631daSSadaf Ebrahimi   // constraint element count.
5773*f5c631daSSadaf Ebrahimi   void uqincd(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1);
5774*f5c631daSSadaf Ebrahimi 
5775*f5c631daSSadaf Ebrahimi   // Unsigned saturating increment vector by multiple of 64-bit predicate
5776*f5c631daSSadaf Ebrahimi   // constraint element count.
5777*f5c631daSSadaf Ebrahimi   void uqincd(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1);
5778*f5c631daSSadaf Ebrahimi 
5779*f5c631daSSadaf Ebrahimi   // Unsigned saturating increment scalar by multiple of 16-bit predicate
5780*f5c631daSSadaf Ebrahimi   // constraint element count.
5781*f5c631daSSadaf Ebrahimi   void uqinch(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1);
5782*f5c631daSSadaf Ebrahimi 
5783*f5c631daSSadaf Ebrahimi   // Unsigned saturating increment vector by multiple of 16-bit predicate
5784*f5c631daSSadaf Ebrahimi   // constraint element count.
5785*f5c631daSSadaf Ebrahimi   void uqinch(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1);
5786*f5c631daSSadaf Ebrahimi 
5787*f5c631daSSadaf Ebrahimi   // Unsigned saturating increment scalar by active predicate element count.
5788*f5c631daSSadaf Ebrahimi   void uqincp(const Register& rdn, const PRegisterWithLaneSize& pg);
5789*f5c631daSSadaf Ebrahimi 
5790*f5c631daSSadaf Ebrahimi   // Unsigned saturating increment vector by active predicate element count.
5791*f5c631daSSadaf Ebrahimi   void uqincp(const ZRegister& zdn, const PRegister& pg);
5792*f5c631daSSadaf Ebrahimi 
5793*f5c631daSSadaf Ebrahimi   // Unsigned saturating increment scalar by multiple of 32-bit predicate
5794*f5c631daSSadaf Ebrahimi   // constraint element count.
5795*f5c631daSSadaf Ebrahimi   void uqincw(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1);
5796*f5c631daSSadaf Ebrahimi 
5797*f5c631daSSadaf Ebrahimi   // Unsigned saturating increment vector by multiple of 32-bit predicate
5798*f5c631daSSadaf Ebrahimi   // constraint element count.
5799*f5c631daSSadaf Ebrahimi   void uqincw(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1);
5800*f5c631daSSadaf Ebrahimi 
5801*f5c631daSSadaf Ebrahimi   // Unsigned saturating subtract vectors (unpredicated).
5802*f5c631daSSadaf Ebrahimi   void uqsub(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
5803*f5c631daSSadaf Ebrahimi 
5804*f5c631daSSadaf Ebrahimi   // Unsigned saturating subtract immediate (unpredicated).
5805*f5c631daSSadaf Ebrahimi   void uqsub(const ZRegister& zd,
5806*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
5807*f5c631daSSadaf Ebrahimi              int imm8,
5808*f5c631daSSadaf Ebrahimi              int shift = -1);
5809*f5c631daSSadaf Ebrahimi 
5810*f5c631daSSadaf Ebrahimi   // Unsigned unpack and extend half of vector.
5811*f5c631daSSadaf Ebrahimi   void uunpkhi(const ZRegister& zd, const ZRegister& zn);
5812*f5c631daSSadaf Ebrahimi 
5813*f5c631daSSadaf Ebrahimi   // Unsigned unpack and extend half of vector.
5814*f5c631daSSadaf Ebrahimi   void uunpklo(const ZRegister& zd, const ZRegister& zn);
5815*f5c631daSSadaf Ebrahimi 
5816*f5c631daSSadaf Ebrahimi   // Unsigned byte extend (predicated).
5817*f5c631daSSadaf Ebrahimi   void uxtb(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
5818*f5c631daSSadaf Ebrahimi 
5819*f5c631daSSadaf Ebrahimi   // Unsigned halfword extend (predicated).
5820*f5c631daSSadaf Ebrahimi   void uxth(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
5821*f5c631daSSadaf Ebrahimi 
5822*f5c631daSSadaf Ebrahimi   // Unsigned word extend (predicated).
5823*f5c631daSSadaf Ebrahimi   void uxtw(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
5824*f5c631daSSadaf Ebrahimi 
5825*f5c631daSSadaf Ebrahimi   // Concatenate even or odd elements from two predicates.
5826*f5c631daSSadaf Ebrahimi   void uzp1(const PRegisterWithLaneSize& pd,
5827*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pn,
5828*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pm);
5829*f5c631daSSadaf Ebrahimi 
5830*f5c631daSSadaf Ebrahimi   // Concatenate even or odd elements from two vectors.
5831*f5c631daSSadaf Ebrahimi   void uzp1(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
5832*f5c631daSSadaf Ebrahimi 
5833*f5c631daSSadaf Ebrahimi   // Concatenate even or odd elements from two predicates.
5834*f5c631daSSadaf Ebrahimi   void uzp2(const PRegisterWithLaneSize& pd,
5835*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pn,
5836*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pm);
5837*f5c631daSSadaf Ebrahimi 
5838*f5c631daSSadaf Ebrahimi   // Concatenate even or odd elements from two vectors.
5839*f5c631daSSadaf Ebrahimi   void uzp2(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
5840*f5c631daSSadaf Ebrahimi 
5841*f5c631daSSadaf Ebrahimi   // While incrementing signed scalar less than or equal to scalar.
5842*f5c631daSSadaf Ebrahimi   void whilele(const PRegisterWithLaneSize& pd,
5843*f5c631daSSadaf Ebrahimi                const Register& rn,
5844*f5c631daSSadaf Ebrahimi                const Register& rm);
5845*f5c631daSSadaf Ebrahimi 
5846*f5c631daSSadaf Ebrahimi   // While incrementing unsigned scalar lower than scalar.
5847*f5c631daSSadaf Ebrahimi   void whilelo(const PRegisterWithLaneSize& pd,
5848*f5c631daSSadaf Ebrahimi                const Register& rn,
5849*f5c631daSSadaf Ebrahimi                const Register& rm);
5850*f5c631daSSadaf Ebrahimi 
5851*f5c631daSSadaf Ebrahimi   // While incrementing unsigned scalar lower or same as scalar.
5852*f5c631daSSadaf Ebrahimi   void whilels(const PRegisterWithLaneSize& pd,
5853*f5c631daSSadaf Ebrahimi                const Register& rn,
5854*f5c631daSSadaf Ebrahimi                const Register& rm);
5855*f5c631daSSadaf Ebrahimi 
5856*f5c631daSSadaf Ebrahimi   // While incrementing signed scalar less than scalar.
5857*f5c631daSSadaf Ebrahimi   void whilelt(const PRegisterWithLaneSize& pd,
5858*f5c631daSSadaf Ebrahimi                const Register& rn,
5859*f5c631daSSadaf Ebrahimi                const Register& rm);
5860*f5c631daSSadaf Ebrahimi 
5861*f5c631daSSadaf Ebrahimi   // Write the first-fault register.
5862*f5c631daSSadaf Ebrahimi   void wrffr(const PRegisterWithLaneSize& pn);
5863*f5c631daSSadaf Ebrahimi 
5864*f5c631daSSadaf Ebrahimi   // Interleave elements from two half predicates.
5865*f5c631daSSadaf Ebrahimi   void zip1(const PRegisterWithLaneSize& pd,
5866*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pn,
5867*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pm);
5868*f5c631daSSadaf Ebrahimi 
5869*f5c631daSSadaf Ebrahimi   // Interleave elements from two half vectors.
5870*f5c631daSSadaf Ebrahimi   void zip1(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
5871*f5c631daSSadaf Ebrahimi 
5872*f5c631daSSadaf Ebrahimi   // Interleave elements from two half predicates.
5873*f5c631daSSadaf Ebrahimi   void zip2(const PRegisterWithLaneSize& pd,
5874*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pn,
5875*f5c631daSSadaf Ebrahimi             const PRegisterWithLaneSize& pm);
5876*f5c631daSSadaf Ebrahimi 
5877*f5c631daSSadaf Ebrahimi   // Interleave elements from two half vectors.
5878*f5c631daSSadaf Ebrahimi   void zip2(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
5879*f5c631daSSadaf Ebrahimi 
5880*f5c631daSSadaf Ebrahimi   // Add with carry long (bottom).
5881*f5c631daSSadaf Ebrahimi   void adclb(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
5882*f5c631daSSadaf Ebrahimi 
5883*f5c631daSSadaf Ebrahimi   // Add with carry long (top).
5884*f5c631daSSadaf Ebrahimi   void adclt(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
5885*f5c631daSSadaf Ebrahimi 
5886*f5c631daSSadaf Ebrahimi   // Add narrow high part (bottom).
5887*f5c631daSSadaf Ebrahimi   void addhnb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
5888*f5c631daSSadaf Ebrahimi 
5889*f5c631daSSadaf Ebrahimi   // Add narrow high part (top).
5890*f5c631daSSadaf Ebrahimi   void addhnt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
5891*f5c631daSSadaf Ebrahimi 
5892*f5c631daSSadaf Ebrahimi   // Add pairwise.
5893*f5c631daSSadaf Ebrahimi   void addp(const ZRegister& zd,
5894*f5c631daSSadaf Ebrahimi             const PRegisterM& pg,
5895*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
5896*f5c631daSSadaf Ebrahimi             const ZRegister& zm);
5897*f5c631daSSadaf Ebrahimi 
5898*f5c631daSSadaf Ebrahimi   // Bitwise clear and exclusive OR.
5899*f5c631daSSadaf Ebrahimi   void bcax(const ZRegister& zd,
5900*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
5901*f5c631daSSadaf Ebrahimi             const ZRegister& zm,
5902*f5c631daSSadaf Ebrahimi             const ZRegister& zk);
5903*f5c631daSSadaf Ebrahimi 
5904*f5c631daSSadaf Ebrahimi   // Scatter lower bits into positions selected by bitmask.
5905*f5c631daSSadaf Ebrahimi   void bdep(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
5906*f5c631daSSadaf Ebrahimi 
5907*f5c631daSSadaf Ebrahimi   // Gather lower bits from positions selected by bitmask.
5908*f5c631daSSadaf Ebrahimi   void bext(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
5909*f5c631daSSadaf Ebrahimi 
5910*f5c631daSSadaf Ebrahimi   // Group bits to right or left as selected by bitmask.
5911*f5c631daSSadaf Ebrahimi   void bgrp(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
5912*f5c631daSSadaf Ebrahimi 
5913*f5c631daSSadaf Ebrahimi   // Bitwise select.
5914*f5c631daSSadaf Ebrahimi   void bsl(const ZRegister& zd,
5915*f5c631daSSadaf Ebrahimi            const ZRegister& zn,
5916*f5c631daSSadaf Ebrahimi            const ZRegister& zm,
5917*f5c631daSSadaf Ebrahimi            const ZRegister& zk);
5918*f5c631daSSadaf Ebrahimi 
5919*f5c631daSSadaf Ebrahimi   // Bitwise select with first input inverted.
5920*f5c631daSSadaf Ebrahimi   void bsl1n(const ZRegister& zd,
5921*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
5922*f5c631daSSadaf Ebrahimi              const ZRegister& zm,
5923*f5c631daSSadaf Ebrahimi              const ZRegister& zk);
5924*f5c631daSSadaf Ebrahimi 
5925*f5c631daSSadaf Ebrahimi   // Bitwise select with second input inverted.
5926*f5c631daSSadaf Ebrahimi   void bsl2n(const ZRegister& zd,
5927*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
5928*f5c631daSSadaf Ebrahimi              const ZRegister& zm,
5929*f5c631daSSadaf Ebrahimi              const ZRegister& zk);
5930*f5c631daSSadaf Ebrahimi 
5931*f5c631daSSadaf Ebrahimi   // Complex integer add with rotate.
5932*f5c631daSSadaf Ebrahimi   void cadd(const ZRegister& zd,
5933*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
5934*f5c631daSSadaf Ebrahimi             const ZRegister& zm,
5935*f5c631daSSadaf Ebrahimi             int rot);
5936*f5c631daSSadaf Ebrahimi 
5937*f5c631daSSadaf Ebrahimi   // Complex integer dot product (indexed).
5938*f5c631daSSadaf Ebrahimi   void cdot(const ZRegister& zda,
5939*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
5940*f5c631daSSadaf Ebrahimi             const ZRegister& zm,
5941*f5c631daSSadaf Ebrahimi             int index,
5942*f5c631daSSadaf Ebrahimi             int rot);
5943*f5c631daSSadaf Ebrahimi 
5944*f5c631daSSadaf Ebrahimi   // Complex integer dot product.
5945*f5c631daSSadaf Ebrahimi   void cdot(const ZRegister& zda,
5946*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
5947*f5c631daSSadaf Ebrahimi             const ZRegister& zm,
5948*f5c631daSSadaf Ebrahimi             int rot);
5949*f5c631daSSadaf Ebrahimi 
5950*f5c631daSSadaf Ebrahimi   // Complex integer multiply-add with rotate (indexed).
5951*f5c631daSSadaf Ebrahimi   void cmla(const ZRegister& zda,
5952*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
5953*f5c631daSSadaf Ebrahimi             const ZRegister& zm,
5954*f5c631daSSadaf Ebrahimi             int index,
5955*f5c631daSSadaf Ebrahimi             int rot);
5956*f5c631daSSadaf Ebrahimi 
5957*f5c631daSSadaf Ebrahimi   // Complex integer multiply-add with rotate.
5958*f5c631daSSadaf Ebrahimi   void cmla(const ZRegister& zda,
5959*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
5960*f5c631daSSadaf Ebrahimi             const ZRegister& zm,
5961*f5c631daSSadaf Ebrahimi             int rot);
5962*f5c631daSSadaf Ebrahimi 
5963*f5c631daSSadaf Ebrahimi   // Bitwise exclusive OR of three vectors.
5964*f5c631daSSadaf Ebrahimi   void eor3(const ZRegister& zd,
5965*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
5966*f5c631daSSadaf Ebrahimi             const ZRegister& zm,
5967*f5c631daSSadaf Ebrahimi             const ZRegister& zk);
5968*f5c631daSSadaf Ebrahimi 
5969*f5c631daSSadaf Ebrahimi   // Interleaving exclusive OR (bottom, top).
5970*f5c631daSSadaf Ebrahimi   void eorbt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
5971*f5c631daSSadaf Ebrahimi 
5972*f5c631daSSadaf Ebrahimi   // Interleaving exclusive OR (top, bottom).
5973*f5c631daSSadaf Ebrahimi   void eortb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
5974*f5c631daSSadaf Ebrahimi 
5975*f5c631daSSadaf Ebrahimi   // Floating-point add pairwise.
5976*f5c631daSSadaf Ebrahimi   void faddp(const ZRegister& zd,
5977*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
5978*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
5979*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
5980*f5c631daSSadaf Ebrahimi 
5981*f5c631daSSadaf Ebrahimi   // Floating-point up convert long (top, predicated).
5982*f5c631daSSadaf Ebrahimi   void fcvtlt(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
5983*f5c631daSSadaf Ebrahimi 
5984*f5c631daSSadaf Ebrahimi   // Floating-point down convert and narrow (top, predicated).
5985*f5c631daSSadaf Ebrahimi   void fcvtnt(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
5986*f5c631daSSadaf Ebrahimi 
5987*f5c631daSSadaf Ebrahimi   // Floating-point down convert, rounding to odd (predicated).
5988*f5c631daSSadaf Ebrahimi   void fcvtx(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
5989*f5c631daSSadaf Ebrahimi 
5990*f5c631daSSadaf Ebrahimi   // Floating-point down convert, rounding to odd (top, predicated).
5991*f5c631daSSadaf Ebrahimi   void fcvtxnt(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
5992*f5c631daSSadaf Ebrahimi 
5993*f5c631daSSadaf Ebrahimi   // Floating-point base 2 logarithm as integer.
5994*f5c631daSSadaf Ebrahimi   void flogb(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
5995*f5c631daSSadaf Ebrahimi 
5996*f5c631daSSadaf Ebrahimi   // Floating-point maximum number pairwise.
5997*f5c631daSSadaf Ebrahimi   void fmaxnmp(const ZRegister& zd,
5998*f5c631daSSadaf Ebrahimi                const PRegisterM& pg,
5999*f5c631daSSadaf Ebrahimi                const ZRegister& zn,
6000*f5c631daSSadaf Ebrahimi                const ZRegister& zm);
6001*f5c631daSSadaf Ebrahimi 
6002*f5c631daSSadaf Ebrahimi   // Floating-point maximum pairwise.
6003*f5c631daSSadaf Ebrahimi   void fmaxp(const ZRegister& zd,
6004*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
6005*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
6006*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
6007*f5c631daSSadaf Ebrahimi 
6008*f5c631daSSadaf Ebrahimi   // Floating-point minimum number pairwise.
6009*f5c631daSSadaf Ebrahimi   void fminnmp(const ZRegister& zd,
6010*f5c631daSSadaf Ebrahimi                const PRegisterM& pg,
6011*f5c631daSSadaf Ebrahimi                const ZRegister& zn,
6012*f5c631daSSadaf Ebrahimi                const ZRegister& zm);
6013*f5c631daSSadaf Ebrahimi 
6014*f5c631daSSadaf Ebrahimi   // Floating-point minimum pairwise.
6015*f5c631daSSadaf Ebrahimi   void fminp(const ZRegister& zd,
6016*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
6017*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
6018*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
6019*f5c631daSSadaf Ebrahimi 
6020*f5c631daSSadaf Ebrahimi   // Half-precision floating-point multiply-add long to single-precision
6021*f5c631daSSadaf Ebrahimi   // (bottom).
6022*f5c631daSSadaf Ebrahimi   void fmlalb(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6023*f5c631daSSadaf Ebrahimi 
6024*f5c631daSSadaf Ebrahimi   // Half-precision floating-point multiply-add long to single-precision
6025*f5c631daSSadaf Ebrahimi   // (top).
6026*f5c631daSSadaf Ebrahimi   void fmlalt(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6027*f5c631daSSadaf Ebrahimi 
6028*f5c631daSSadaf Ebrahimi   // Half-precision floating-point multiply-subtract long from
6029*f5c631daSSadaf Ebrahimi   // single-precision (bottom).
6030*f5c631daSSadaf Ebrahimi   void fmlslb(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6031*f5c631daSSadaf Ebrahimi 
6032*f5c631daSSadaf Ebrahimi   // Half-precision floating-point multiply-subtract long from
6033*f5c631daSSadaf Ebrahimi   // single-precision (top, indexed).
6034*f5c631daSSadaf Ebrahimi   void fmlslt(const ZRegister& zda,
6035*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6036*f5c631daSSadaf Ebrahimi               const ZRegister& zm,
6037*f5c631daSSadaf Ebrahimi               int index);
6038*f5c631daSSadaf Ebrahimi 
6039*f5c631daSSadaf Ebrahimi   // Half-precision floating-point multiply-add long to single-precision
6040*f5c631daSSadaf Ebrahimi   // (bottom, indexed).
6041*f5c631daSSadaf Ebrahimi   void fmlalb(const ZRegister& zda,
6042*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6043*f5c631daSSadaf Ebrahimi               const ZRegister& zm,
6044*f5c631daSSadaf Ebrahimi               int index);
6045*f5c631daSSadaf Ebrahimi 
6046*f5c631daSSadaf Ebrahimi   // Half-precision floating-point multiply-add long to single-precision
6047*f5c631daSSadaf Ebrahimi   // (top, indexed).
6048*f5c631daSSadaf Ebrahimi   void fmlalt(const ZRegister& zda,
6049*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6050*f5c631daSSadaf Ebrahimi               const ZRegister& zm,
6051*f5c631daSSadaf Ebrahimi               int index);
6052*f5c631daSSadaf Ebrahimi 
6053*f5c631daSSadaf Ebrahimi   // Half-precision floating-point multiply-subtract long from
6054*f5c631daSSadaf Ebrahimi   // single-precision (bottom, indexed).
6055*f5c631daSSadaf Ebrahimi   void fmlslb(const ZRegister& zda,
6056*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6057*f5c631daSSadaf Ebrahimi               const ZRegister& zm,
6058*f5c631daSSadaf Ebrahimi               int index);
6059*f5c631daSSadaf Ebrahimi 
6060*f5c631daSSadaf Ebrahimi   // Half-precision floating-point multiply-subtract long from
6061*f5c631daSSadaf Ebrahimi   // single-precision (top).
6062*f5c631daSSadaf Ebrahimi   void fmlslt(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6063*f5c631daSSadaf Ebrahimi 
6064*f5c631daSSadaf Ebrahimi   // Count matching elements in vector.
6065*f5c631daSSadaf Ebrahimi   void histcnt(const ZRegister& zd,
6066*f5c631daSSadaf Ebrahimi                const PRegisterZ& pg,
6067*f5c631daSSadaf Ebrahimi                const ZRegister& zn,
6068*f5c631daSSadaf Ebrahimi                const ZRegister& zm);
6069*f5c631daSSadaf Ebrahimi 
6070*f5c631daSSadaf Ebrahimi   // Count matching elements in vector segments.
6071*f5c631daSSadaf Ebrahimi   void histseg(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6072*f5c631daSSadaf Ebrahimi 
6073*f5c631daSSadaf Ebrahimi   // Gather load non-temporal signed bytes.
6074*f5c631daSSadaf Ebrahimi   void ldnt1sb(const ZRegister& zt,
6075*f5c631daSSadaf Ebrahimi                const PRegisterZ& pg,
6076*f5c631daSSadaf Ebrahimi                const SVEMemOperand& addr);
6077*f5c631daSSadaf Ebrahimi 
6078*f5c631daSSadaf Ebrahimi   // Gather load non-temporal signed halfwords.
6079*f5c631daSSadaf Ebrahimi   void ldnt1sh(const ZRegister& zt,
6080*f5c631daSSadaf Ebrahimi                const PRegisterZ& pg,
6081*f5c631daSSadaf Ebrahimi                const SVEMemOperand& addr);
6082*f5c631daSSadaf Ebrahimi 
6083*f5c631daSSadaf Ebrahimi   // Gather load non-temporal signed words.
6084*f5c631daSSadaf Ebrahimi   void ldnt1sw(const ZRegister& zt,
6085*f5c631daSSadaf Ebrahimi                const PRegisterZ& pg,
6086*f5c631daSSadaf Ebrahimi                const SVEMemOperand& addr);
6087*f5c631daSSadaf Ebrahimi 
6088*f5c631daSSadaf Ebrahimi   // Detect any matching elements, setting the condition flags.
6089*f5c631daSSadaf Ebrahimi   void match(const PRegisterWithLaneSize& pd,
6090*f5c631daSSadaf Ebrahimi              const PRegisterZ& pg,
6091*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
6092*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
6093*f5c631daSSadaf Ebrahimi 
6094*f5c631daSSadaf Ebrahimi   // Multiply-add to accumulator (indexed).
6095*f5c631daSSadaf Ebrahimi   void mla(const ZRegister& zda,
6096*f5c631daSSadaf Ebrahimi            const ZRegister& zn,
6097*f5c631daSSadaf Ebrahimi            const ZRegister& zm,
6098*f5c631daSSadaf Ebrahimi            int index);
6099*f5c631daSSadaf Ebrahimi 
6100*f5c631daSSadaf Ebrahimi   // Multiply-subtract from accumulator (indexed).
6101*f5c631daSSadaf Ebrahimi   void mls(const ZRegister& zda,
6102*f5c631daSSadaf Ebrahimi            const ZRegister& zn,
6103*f5c631daSSadaf Ebrahimi            const ZRegister& zm,
6104*f5c631daSSadaf Ebrahimi            int index);
6105*f5c631daSSadaf Ebrahimi 
6106*f5c631daSSadaf Ebrahimi   // Multiply (indexed).
6107*f5c631daSSadaf Ebrahimi   void mul(const ZRegister& zd,
6108*f5c631daSSadaf Ebrahimi            const ZRegister& zn,
6109*f5c631daSSadaf Ebrahimi            const ZRegister& zm,
6110*f5c631daSSadaf Ebrahimi            int index);
6111*f5c631daSSadaf Ebrahimi 
6112*f5c631daSSadaf Ebrahimi   // Multiply vectors (unpredicated).
6113*f5c631daSSadaf Ebrahimi   void mul(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6114*f5c631daSSadaf Ebrahimi 
6115*f5c631daSSadaf Ebrahimi   // Bitwise inverted select.
6116*f5c631daSSadaf Ebrahimi   void nbsl(const ZRegister& zd,
6117*f5c631daSSadaf Ebrahimi             const ZRegister& zn,
6118*f5c631daSSadaf Ebrahimi             const ZRegister& zm,
6119*f5c631daSSadaf Ebrahimi             const ZRegister& zk);
6120*f5c631daSSadaf Ebrahimi 
6121*f5c631daSSadaf Ebrahimi   // Detect no matching elements, setting the condition flags.
6122*f5c631daSSadaf Ebrahimi   void nmatch(const PRegisterWithLaneSize& pd,
6123*f5c631daSSadaf Ebrahimi               const PRegisterZ& pg,
6124*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6125*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
6126*f5c631daSSadaf Ebrahimi 
6127*f5c631daSSadaf Ebrahimi   // Polynomial multiply vectors (unpredicated).
6128*f5c631daSSadaf Ebrahimi   void pmul(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6129*f5c631daSSadaf Ebrahimi 
6130*f5c631daSSadaf Ebrahimi   // Polynomial multiply long (bottom).
6131*f5c631daSSadaf Ebrahimi   void pmullb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6132*f5c631daSSadaf Ebrahimi 
6133*f5c631daSSadaf Ebrahimi   // Polynomial multiply long (top).
6134*f5c631daSSadaf Ebrahimi   void pmullt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6135*f5c631daSSadaf Ebrahimi 
6136*f5c631daSSadaf Ebrahimi   // Rounding add narrow high part (bottom).
6137*f5c631daSSadaf Ebrahimi   void raddhnb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6138*f5c631daSSadaf Ebrahimi 
6139*f5c631daSSadaf Ebrahimi   // Rounding add narrow high part (top).
6140*f5c631daSSadaf Ebrahimi   void raddhnt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6141*f5c631daSSadaf Ebrahimi 
6142*f5c631daSSadaf Ebrahimi   // Rounding shift right narrow by immediate (bottom).
6143*f5c631daSSadaf Ebrahimi   void rshrnb(const ZRegister& zd, const ZRegister& zn, int shift);
6144*f5c631daSSadaf Ebrahimi 
6145*f5c631daSSadaf Ebrahimi   // Rounding shift right narrow by immediate (top).
6146*f5c631daSSadaf Ebrahimi   void rshrnt(const ZRegister& zd, const ZRegister& zn, int shift);
6147*f5c631daSSadaf Ebrahimi 
6148*f5c631daSSadaf Ebrahimi   // Rounding subtract narrow high part (bottom).
6149*f5c631daSSadaf Ebrahimi   void rsubhnb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6150*f5c631daSSadaf Ebrahimi 
6151*f5c631daSSadaf Ebrahimi   // Rounding subtract narrow high part (top).
6152*f5c631daSSadaf Ebrahimi   void rsubhnt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6153*f5c631daSSadaf Ebrahimi 
6154*f5c631daSSadaf Ebrahimi   // Signed absolute difference and accumulate.
6155*f5c631daSSadaf Ebrahimi   void saba(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6156*f5c631daSSadaf Ebrahimi 
6157*f5c631daSSadaf Ebrahimi   // Signed absolute difference and accumulate long (bottom).
6158*f5c631daSSadaf Ebrahimi   void sabalb(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6159*f5c631daSSadaf Ebrahimi 
6160*f5c631daSSadaf Ebrahimi   // Signed absolute difference and accumulate long (top).
6161*f5c631daSSadaf Ebrahimi   void sabalt(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6162*f5c631daSSadaf Ebrahimi 
6163*f5c631daSSadaf Ebrahimi   // Signed absolute difference long (bottom).
6164*f5c631daSSadaf Ebrahimi   void sabdlb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6165*f5c631daSSadaf Ebrahimi 
6166*f5c631daSSadaf Ebrahimi   // Signed absolute difference long (top).
6167*f5c631daSSadaf Ebrahimi   void sabdlt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6168*f5c631daSSadaf Ebrahimi 
6169*f5c631daSSadaf Ebrahimi   // Signed add and accumulate long pairwise.
6170*f5c631daSSadaf Ebrahimi   void sadalp(const ZRegister& zda, const PRegisterM& pg, const ZRegister& zn);
6171*f5c631daSSadaf Ebrahimi 
6172*f5c631daSSadaf Ebrahimi   // Signed add long (bottom).
6173*f5c631daSSadaf Ebrahimi   void saddlb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6174*f5c631daSSadaf Ebrahimi 
6175*f5c631daSSadaf Ebrahimi   // Signed add long (bottom + top).
6176*f5c631daSSadaf Ebrahimi   void saddlbt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6177*f5c631daSSadaf Ebrahimi 
6178*f5c631daSSadaf Ebrahimi   // Signed add long (top).
6179*f5c631daSSadaf Ebrahimi   void saddlt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6180*f5c631daSSadaf Ebrahimi 
6181*f5c631daSSadaf Ebrahimi   // Signed add wide (bottom).
6182*f5c631daSSadaf Ebrahimi   void saddwb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6183*f5c631daSSadaf Ebrahimi 
6184*f5c631daSSadaf Ebrahimi   // Signed add wide (top).
6185*f5c631daSSadaf Ebrahimi   void saddwt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6186*f5c631daSSadaf Ebrahimi 
6187*f5c631daSSadaf Ebrahimi   // Subtract with carry long (bottom).
6188*f5c631daSSadaf Ebrahimi   void sbclb(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6189*f5c631daSSadaf Ebrahimi 
6190*f5c631daSSadaf Ebrahimi   // Subtract with carry long (top).
6191*f5c631daSSadaf Ebrahimi   void sbclt(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6192*f5c631daSSadaf Ebrahimi 
6193*f5c631daSSadaf Ebrahimi   // Signed halving addition.
6194*f5c631daSSadaf Ebrahimi   void shadd(const ZRegister& zd,
6195*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
6196*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
6197*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
6198*f5c631daSSadaf Ebrahimi 
6199*f5c631daSSadaf Ebrahimi   // Shift right narrow by immediate (bottom).
6200*f5c631daSSadaf Ebrahimi   void shrnb(const ZRegister& zd, const ZRegister& zn, int shift);
6201*f5c631daSSadaf Ebrahimi 
6202*f5c631daSSadaf Ebrahimi   // Shift right narrow by immediate (top).
6203*f5c631daSSadaf Ebrahimi   void shrnt(const ZRegister& zd, const ZRegister& zn, int shift);
6204*f5c631daSSadaf Ebrahimi 
6205*f5c631daSSadaf Ebrahimi   // Signed halving subtract.
6206*f5c631daSSadaf Ebrahimi   void shsub(const ZRegister& zd,
6207*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
6208*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
6209*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
6210*f5c631daSSadaf Ebrahimi 
6211*f5c631daSSadaf Ebrahimi   // Signed halving subtract reversed vectors.
6212*f5c631daSSadaf Ebrahimi   void shsubr(const ZRegister& zd,
6213*f5c631daSSadaf Ebrahimi               const PRegisterM& pg,
6214*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6215*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
6216*f5c631daSSadaf Ebrahimi 
6217*f5c631daSSadaf Ebrahimi   // Shift left and insert (immediate).
6218*f5c631daSSadaf Ebrahimi   void sli(const ZRegister& zd, const ZRegister& zn, int shift);
6219*f5c631daSSadaf Ebrahimi 
6220*f5c631daSSadaf Ebrahimi   // Signed maximum pairwise.
6221*f5c631daSSadaf Ebrahimi   void smaxp(const ZRegister& zd,
6222*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
6223*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
6224*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
6225*f5c631daSSadaf Ebrahimi 
6226*f5c631daSSadaf Ebrahimi   // Signed minimum pairwise.
6227*f5c631daSSadaf Ebrahimi   void sminp(const ZRegister& zd,
6228*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
6229*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
6230*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
6231*f5c631daSSadaf Ebrahimi 
6232*f5c631daSSadaf Ebrahimi   // Signed multiply-add long to accumulator (bottom, indexed).
6233*f5c631daSSadaf Ebrahimi   void smlalb(const ZRegister& zda,
6234*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6235*f5c631daSSadaf Ebrahimi               const ZRegister& zm,
6236*f5c631daSSadaf Ebrahimi               int index);
6237*f5c631daSSadaf Ebrahimi 
6238*f5c631daSSadaf Ebrahimi   // Signed multiply-add long to accumulator (bottom).
6239*f5c631daSSadaf Ebrahimi   void smlalb(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6240*f5c631daSSadaf Ebrahimi 
6241*f5c631daSSadaf Ebrahimi   // Signed multiply-add long to accumulator (top, indexed).
6242*f5c631daSSadaf Ebrahimi   void smlalt(const ZRegister& zda,
6243*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6244*f5c631daSSadaf Ebrahimi               const ZRegister& zm,
6245*f5c631daSSadaf Ebrahimi               int index);
6246*f5c631daSSadaf Ebrahimi 
6247*f5c631daSSadaf Ebrahimi   // Signed multiply-add long to accumulator (top).
6248*f5c631daSSadaf Ebrahimi   void smlalt(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6249*f5c631daSSadaf Ebrahimi 
6250*f5c631daSSadaf Ebrahimi   // Signed multiply-subtract long from accumulator (bottom, indexed).
6251*f5c631daSSadaf Ebrahimi   void smlslb(const ZRegister& zda,
6252*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6253*f5c631daSSadaf Ebrahimi               const ZRegister& zm,
6254*f5c631daSSadaf Ebrahimi               int index);
6255*f5c631daSSadaf Ebrahimi 
6256*f5c631daSSadaf Ebrahimi   // Signed multiply-subtract long from accumulator (bottom).
6257*f5c631daSSadaf Ebrahimi   void smlslb(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6258*f5c631daSSadaf Ebrahimi 
6259*f5c631daSSadaf Ebrahimi   // Signed multiply-subtract long from accumulator (top, indexed).
6260*f5c631daSSadaf Ebrahimi   void smlslt(const ZRegister& zda,
6261*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6262*f5c631daSSadaf Ebrahimi               const ZRegister& zm,
6263*f5c631daSSadaf Ebrahimi               int index);
6264*f5c631daSSadaf Ebrahimi 
6265*f5c631daSSadaf Ebrahimi   // Signed multiply-subtract long from accumulator (top).
6266*f5c631daSSadaf Ebrahimi   void smlslt(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6267*f5c631daSSadaf Ebrahimi 
6268*f5c631daSSadaf Ebrahimi   // Signed multiply returning high half (unpredicated).
6269*f5c631daSSadaf Ebrahimi   void smulh(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6270*f5c631daSSadaf Ebrahimi 
6271*f5c631daSSadaf Ebrahimi   // Signed multiply long (bottom, indexed).
6272*f5c631daSSadaf Ebrahimi   void smullb(const ZRegister& zd,
6273*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6274*f5c631daSSadaf Ebrahimi               const ZRegister& zm,
6275*f5c631daSSadaf Ebrahimi               int index);
6276*f5c631daSSadaf Ebrahimi 
6277*f5c631daSSadaf Ebrahimi   // Signed multiply long (bottom).
6278*f5c631daSSadaf Ebrahimi   void smullb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6279*f5c631daSSadaf Ebrahimi 
6280*f5c631daSSadaf Ebrahimi   // Signed multiply long (top, indexed).
6281*f5c631daSSadaf Ebrahimi   void smullt(const ZRegister& zd,
6282*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6283*f5c631daSSadaf Ebrahimi               const ZRegister& zm,
6284*f5c631daSSadaf Ebrahimi               int index);
6285*f5c631daSSadaf Ebrahimi 
6286*f5c631daSSadaf Ebrahimi   // Signed multiply long (top).
6287*f5c631daSSadaf Ebrahimi   void smullt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6288*f5c631daSSadaf Ebrahimi 
6289*f5c631daSSadaf Ebrahimi   // Signed saturating absolute value.
6290*f5c631daSSadaf Ebrahimi   void sqabs(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
6291*f5c631daSSadaf Ebrahimi 
6292*f5c631daSSadaf Ebrahimi   // Signed saturating addition (predicated).
6293*f5c631daSSadaf Ebrahimi   void sqadd(const ZRegister& zd,
6294*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
6295*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
6296*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
6297*f5c631daSSadaf Ebrahimi 
6298*f5c631daSSadaf Ebrahimi   // Saturating complex integer add with rotate.
6299*f5c631daSSadaf Ebrahimi   void sqcadd(const ZRegister& zd,
6300*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6301*f5c631daSSadaf Ebrahimi               const ZRegister& zm,
6302*f5c631daSSadaf Ebrahimi               int rot);
6303*f5c631daSSadaf Ebrahimi 
6304*f5c631daSSadaf Ebrahimi   // Signed saturating doubling multiply-add long to accumulator (bottom,
6305*f5c631daSSadaf Ebrahimi   // indexed).
6306*f5c631daSSadaf Ebrahimi   void sqdmlalb(const ZRegister& zda,
6307*f5c631daSSadaf Ebrahimi                 const ZRegister& zn,
6308*f5c631daSSadaf Ebrahimi                 const ZRegister& zm,
6309*f5c631daSSadaf Ebrahimi                 int index);
6310*f5c631daSSadaf Ebrahimi 
6311*f5c631daSSadaf Ebrahimi   // Signed saturating doubling multiply-add long to accumulator (bottom).
6312*f5c631daSSadaf Ebrahimi   void sqdmlalb(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6313*f5c631daSSadaf Ebrahimi 
6314*f5c631daSSadaf Ebrahimi   // Signed saturating doubling multiply-add long to accumulator (bottom x
6315*f5c631daSSadaf Ebrahimi   // top).
6316*f5c631daSSadaf Ebrahimi   void sqdmlalbt(const ZRegister& zda,
6317*f5c631daSSadaf Ebrahimi                  const ZRegister& zn,
6318*f5c631daSSadaf Ebrahimi                  const ZRegister& zm);
6319*f5c631daSSadaf Ebrahimi 
6320*f5c631daSSadaf Ebrahimi   // Signed saturating doubling multiply-add long to accumulator (top,
6321*f5c631daSSadaf Ebrahimi   // indexed).
6322*f5c631daSSadaf Ebrahimi   void sqdmlalt(const ZRegister& zda,
6323*f5c631daSSadaf Ebrahimi                 const ZRegister& zn,
6324*f5c631daSSadaf Ebrahimi                 const ZRegister& zm,
6325*f5c631daSSadaf Ebrahimi                 int index);
6326*f5c631daSSadaf Ebrahimi 
6327*f5c631daSSadaf Ebrahimi   // Signed saturating doubling multiply-add long to accumulator (top).
6328*f5c631daSSadaf Ebrahimi   void sqdmlalt(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6329*f5c631daSSadaf Ebrahimi 
6330*f5c631daSSadaf Ebrahimi   // Signed saturating doubling multiply-subtract long from accumulator
6331*f5c631daSSadaf Ebrahimi   // (bottom, indexed).
6332*f5c631daSSadaf Ebrahimi   void sqdmlslb(const ZRegister& zda,
6333*f5c631daSSadaf Ebrahimi                 const ZRegister& zn,
6334*f5c631daSSadaf Ebrahimi                 const ZRegister& zm,
6335*f5c631daSSadaf Ebrahimi                 int index);
6336*f5c631daSSadaf Ebrahimi 
6337*f5c631daSSadaf Ebrahimi   // Signed saturating doubling multiply-subtract long from accumulator
6338*f5c631daSSadaf Ebrahimi   // (bottom).
6339*f5c631daSSadaf Ebrahimi   void sqdmlslb(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6340*f5c631daSSadaf Ebrahimi 
6341*f5c631daSSadaf Ebrahimi   // Signed saturating doubling multiply-subtract long from accumulator
6342*f5c631daSSadaf Ebrahimi   // (bottom x top).
6343*f5c631daSSadaf Ebrahimi   void sqdmlslbt(const ZRegister& zda,
6344*f5c631daSSadaf Ebrahimi                  const ZRegister& zn,
6345*f5c631daSSadaf Ebrahimi                  const ZRegister& zm);
6346*f5c631daSSadaf Ebrahimi 
6347*f5c631daSSadaf Ebrahimi   // Signed saturating doubling multiply-subtract long from accumulator
6348*f5c631daSSadaf Ebrahimi   // (top, indexed).
6349*f5c631daSSadaf Ebrahimi   void sqdmlslt(const ZRegister& zda,
6350*f5c631daSSadaf Ebrahimi                 const ZRegister& zn,
6351*f5c631daSSadaf Ebrahimi                 const ZRegister& zm,
6352*f5c631daSSadaf Ebrahimi                 int index);
6353*f5c631daSSadaf Ebrahimi 
6354*f5c631daSSadaf Ebrahimi   // Signed saturating doubling multiply-subtract long from accumulator
6355*f5c631daSSadaf Ebrahimi   // (top).
6356*f5c631daSSadaf Ebrahimi   void sqdmlslt(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6357*f5c631daSSadaf Ebrahimi 
6358*f5c631daSSadaf Ebrahimi   // Signed saturating doubling multiply high (indexed).
6359*f5c631daSSadaf Ebrahimi   void sqdmulh(const ZRegister& zd,
6360*f5c631daSSadaf Ebrahimi                const ZRegister& zn,
6361*f5c631daSSadaf Ebrahimi                const ZRegister& zm,
6362*f5c631daSSadaf Ebrahimi                int index);
6363*f5c631daSSadaf Ebrahimi 
6364*f5c631daSSadaf Ebrahimi   // Signed saturating doubling multiply high (unpredicated).
6365*f5c631daSSadaf Ebrahimi   void sqdmulh(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6366*f5c631daSSadaf Ebrahimi 
6367*f5c631daSSadaf Ebrahimi   // Signed saturating doubling multiply long (bottom, indexed).
6368*f5c631daSSadaf Ebrahimi   void sqdmullb(const ZRegister& zd,
6369*f5c631daSSadaf Ebrahimi                 const ZRegister& zn,
6370*f5c631daSSadaf Ebrahimi                 const ZRegister& zm,
6371*f5c631daSSadaf Ebrahimi                 int index);
6372*f5c631daSSadaf Ebrahimi 
6373*f5c631daSSadaf Ebrahimi   // Signed saturating doubling multiply long (bottom).
6374*f5c631daSSadaf Ebrahimi   void sqdmullb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6375*f5c631daSSadaf Ebrahimi 
6376*f5c631daSSadaf Ebrahimi   // Signed saturating doubling multiply long (top, indexed).
6377*f5c631daSSadaf Ebrahimi   void sqdmullt(const ZRegister& zd,
6378*f5c631daSSadaf Ebrahimi                 const ZRegister& zn,
6379*f5c631daSSadaf Ebrahimi                 const ZRegister& zm,
6380*f5c631daSSadaf Ebrahimi                 int index);
6381*f5c631daSSadaf Ebrahimi 
6382*f5c631daSSadaf Ebrahimi   // Signed saturating doubling multiply long (top).
6383*f5c631daSSadaf Ebrahimi   void sqdmullt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6384*f5c631daSSadaf Ebrahimi 
6385*f5c631daSSadaf Ebrahimi   // Signed saturating negate.
6386*f5c631daSSadaf Ebrahimi   void sqneg(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
6387*f5c631daSSadaf Ebrahimi 
6388*f5c631daSSadaf Ebrahimi   // Saturating rounding doubling complex integer multiply-add high with
6389*f5c631daSSadaf Ebrahimi   // rotate (indexed).
6390*f5c631daSSadaf Ebrahimi   void sqrdcmlah(const ZRegister& zda,
6391*f5c631daSSadaf Ebrahimi                  const ZRegister& zn,
6392*f5c631daSSadaf Ebrahimi                  const ZRegister& zm,
6393*f5c631daSSadaf Ebrahimi                  int index,
6394*f5c631daSSadaf Ebrahimi                  int rot);
6395*f5c631daSSadaf Ebrahimi 
6396*f5c631daSSadaf Ebrahimi   // Saturating rounding doubling complex integer multiply-add high with
6397*f5c631daSSadaf Ebrahimi   // rotate.
6398*f5c631daSSadaf Ebrahimi   void sqrdcmlah(const ZRegister& zda,
6399*f5c631daSSadaf Ebrahimi                  const ZRegister& zn,
6400*f5c631daSSadaf Ebrahimi                  const ZRegister& zm,
6401*f5c631daSSadaf Ebrahimi                  int rot);
6402*f5c631daSSadaf Ebrahimi 
6403*f5c631daSSadaf Ebrahimi   // Signed saturating rounding doubling multiply-add high to accumulator
6404*f5c631daSSadaf Ebrahimi   // (indexed).
6405*f5c631daSSadaf Ebrahimi   void sqrdmlah(const ZRegister& zda,
6406*f5c631daSSadaf Ebrahimi                 const ZRegister& zn,
6407*f5c631daSSadaf Ebrahimi                 const ZRegister& zm,
6408*f5c631daSSadaf Ebrahimi                 int index);
6409*f5c631daSSadaf Ebrahimi 
6410*f5c631daSSadaf Ebrahimi   // Signed saturating rounding doubling multiply-add high to accumulator
6411*f5c631daSSadaf Ebrahimi   // (unpredicated).
6412*f5c631daSSadaf Ebrahimi   void sqrdmlah(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6413*f5c631daSSadaf Ebrahimi 
6414*f5c631daSSadaf Ebrahimi   // Signed saturating rounding doubling multiply-subtract high from
6415*f5c631daSSadaf Ebrahimi   // accumulator (indexed).
6416*f5c631daSSadaf Ebrahimi   void sqrdmlsh(const ZRegister& zda,
6417*f5c631daSSadaf Ebrahimi                 const ZRegister& zn,
6418*f5c631daSSadaf Ebrahimi                 const ZRegister& zm,
6419*f5c631daSSadaf Ebrahimi                 int index);
6420*f5c631daSSadaf Ebrahimi 
6421*f5c631daSSadaf Ebrahimi   // Signed saturating rounding doubling multiply-subtract high from
6422*f5c631daSSadaf Ebrahimi   // accumulator (unpredicated).
6423*f5c631daSSadaf Ebrahimi   void sqrdmlsh(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6424*f5c631daSSadaf Ebrahimi 
6425*f5c631daSSadaf Ebrahimi   // Signed saturating rounding doubling multiply high (indexed).
6426*f5c631daSSadaf Ebrahimi   void sqrdmulh(const ZRegister& zd,
6427*f5c631daSSadaf Ebrahimi                 const ZRegister& zn,
6428*f5c631daSSadaf Ebrahimi                 const ZRegister& zm,
6429*f5c631daSSadaf Ebrahimi                 int index);
6430*f5c631daSSadaf Ebrahimi 
6431*f5c631daSSadaf Ebrahimi   // Signed saturating rounding doubling multiply high (unpredicated).
6432*f5c631daSSadaf Ebrahimi   void sqrdmulh(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6433*f5c631daSSadaf Ebrahimi 
6434*f5c631daSSadaf Ebrahimi   // Signed saturating rounding shift left by vector (predicated).
6435*f5c631daSSadaf Ebrahimi   void sqrshl(const ZRegister& zd,
6436*f5c631daSSadaf Ebrahimi               const PRegisterM& pg,
6437*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6438*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
6439*f5c631daSSadaf Ebrahimi 
6440*f5c631daSSadaf Ebrahimi   // Signed saturating rounding shift left reversed vectors (predicated).
6441*f5c631daSSadaf Ebrahimi   void sqrshlr(const ZRegister& zd,
6442*f5c631daSSadaf Ebrahimi                const PRegisterM& pg,
6443*f5c631daSSadaf Ebrahimi                const ZRegister& zn,
6444*f5c631daSSadaf Ebrahimi                const ZRegister& zm);
6445*f5c631daSSadaf Ebrahimi 
6446*f5c631daSSadaf Ebrahimi   // Signed saturating rounding shift right narrow by immediate (bottom).
6447*f5c631daSSadaf Ebrahimi   void sqrshrnb(const ZRegister& zd, const ZRegister& zn, int shift);
6448*f5c631daSSadaf Ebrahimi 
6449*f5c631daSSadaf Ebrahimi   // Signed saturating rounding shift right narrow by immediate (top).
6450*f5c631daSSadaf Ebrahimi   void sqrshrnt(const ZRegister& zd, const ZRegister& zn, int shift);
6451*f5c631daSSadaf Ebrahimi 
6452*f5c631daSSadaf Ebrahimi   // Signed saturating rounding shift right unsigned narrow by immediate
6453*f5c631daSSadaf Ebrahimi   // (bottom).
6454*f5c631daSSadaf Ebrahimi   void sqrshrunb(const ZRegister& zd, const ZRegister& zn, int shift);
6455*f5c631daSSadaf Ebrahimi 
6456*f5c631daSSadaf Ebrahimi   // Signed saturating rounding shift right unsigned narrow by immediate
6457*f5c631daSSadaf Ebrahimi   // (top).
6458*f5c631daSSadaf Ebrahimi   void sqrshrunt(const ZRegister& zd, const ZRegister& zn, int shift);
6459*f5c631daSSadaf Ebrahimi 
6460*f5c631daSSadaf Ebrahimi   // Signed saturating shift left by immediate.
6461*f5c631daSSadaf Ebrahimi   void sqshl(const ZRegister& zd,
6462*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
6463*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
6464*f5c631daSSadaf Ebrahimi              int shift);
6465*f5c631daSSadaf Ebrahimi 
6466*f5c631daSSadaf Ebrahimi   // Signed saturating shift left by vector (predicated).
6467*f5c631daSSadaf Ebrahimi   void sqshl(const ZRegister& zd,
6468*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
6469*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
6470*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
6471*f5c631daSSadaf Ebrahimi 
6472*f5c631daSSadaf Ebrahimi   // Signed saturating shift left reversed vectors (predicated).
6473*f5c631daSSadaf Ebrahimi   void sqshlr(const ZRegister& zd,
6474*f5c631daSSadaf Ebrahimi               const PRegisterM& pg,
6475*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6476*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
6477*f5c631daSSadaf Ebrahimi 
6478*f5c631daSSadaf Ebrahimi   // Signed saturating shift left unsigned by immediate.
6479*f5c631daSSadaf Ebrahimi   void sqshlu(const ZRegister& zd,
6480*f5c631daSSadaf Ebrahimi               const PRegisterM& pg,
6481*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6482*f5c631daSSadaf Ebrahimi               int shift);
6483*f5c631daSSadaf Ebrahimi 
6484*f5c631daSSadaf Ebrahimi   // Signed saturating shift right narrow by immediate (bottom).
6485*f5c631daSSadaf Ebrahimi   void sqshrnb(const ZRegister& zd, const ZRegister& zn, int shift);
6486*f5c631daSSadaf Ebrahimi 
6487*f5c631daSSadaf Ebrahimi   // Signed saturating shift right narrow by immediate (top).
6488*f5c631daSSadaf Ebrahimi   void sqshrnt(const ZRegister& zd, const ZRegister& zn, int shift);
6489*f5c631daSSadaf Ebrahimi 
6490*f5c631daSSadaf Ebrahimi   // Signed saturating shift right unsigned narrow by immediate (bottom).
6491*f5c631daSSadaf Ebrahimi   void sqshrunb(const ZRegister& zd, const ZRegister& zn, int shift);
6492*f5c631daSSadaf Ebrahimi 
6493*f5c631daSSadaf Ebrahimi   // Signed saturating shift right unsigned narrow by immediate (top).
6494*f5c631daSSadaf Ebrahimi   void sqshrunt(const ZRegister& zd, const ZRegister& zn, int shift);
6495*f5c631daSSadaf Ebrahimi 
6496*f5c631daSSadaf Ebrahimi   // Signed saturating subtraction (predicated).
6497*f5c631daSSadaf Ebrahimi   void sqsub(const ZRegister& zd,
6498*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
6499*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
6500*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
6501*f5c631daSSadaf Ebrahimi 
6502*f5c631daSSadaf Ebrahimi   // Signed saturating subtraction reversed vectors (predicated).
6503*f5c631daSSadaf Ebrahimi   void sqsubr(const ZRegister& zd,
6504*f5c631daSSadaf Ebrahimi               const PRegisterM& pg,
6505*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6506*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
6507*f5c631daSSadaf Ebrahimi 
6508*f5c631daSSadaf Ebrahimi   // Signed saturating extract narrow (bottom).
6509*f5c631daSSadaf Ebrahimi   void sqxtnb(const ZRegister& zd, const ZRegister& zn);
6510*f5c631daSSadaf Ebrahimi 
6511*f5c631daSSadaf Ebrahimi   // Signed saturating extract narrow (top).
6512*f5c631daSSadaf Ebrahimi   void sqxtnt(const ZRegister& zd, const ZRegister& zn);
6513*f5c631daSSadaf Ebrahimi 
6514*f5c631daSSadaf Ebrahimi   // Signed saturating unsigned extract narrow (bottom).
6515*f5c631daSSadaf Ebrahimi   void sqxtunb(const ZRegister& zd, const ZRegister& zn);
6516*f5c631daSSadaf Ebrahimi 
6517*f5c631daSSadaf Ebrahimi   // Signed saturating unsigned extract narrow (top).
6518*f5c631daSSadaf Ebrahimi   void sqxtunt(const ZRegister& zd, const ZRegister& zn);
6519*f5c631daSSadaf Ebrahimi 
6520*f5c631daSSadaf Ebrahimi   // Signed rounding halving addition.
6521*f5c631daSSadaf Ebrahimi   void srhadd(const ZRegister& zd,
6522*f5c631daSSadaf Ebrahimi               const PRegisterM& pg,
6523*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6524*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
6525*f5c631daSSadaf Ebrahimi 
6526*f5c631daSSadaf Ebrahimi   // Shift right and insert (immediate).
6527*f5c631daSSadaf Ebrahimi   void sri(const ZRegister& zd, const ZRegister& zn, int shift);
6528*f5c631daSSadaf Ebrahimi 
6529*f5c631daSSadaf Ebrahimi   // Signed rounding shift left by vector (predicated).
6530*f5c631daSSadaf Ebrahimi   void srshl(const ZRegister& zd,
6531*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
6532*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
6533*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
6534*f5c631daSSadaf Ebrahimi 
6535*f5c631daSSadaf Ebrahimi   // Signed rounding shift left reversed vectors (predicated).
6536*f5c631daSSadaf Ebrahimi   void srshlr(const ZRegister& zd,
6537*f5c631daSSadaf Ebrahimi               const PRegisterM& pg,
6538*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6539*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
6540*f5c631daSSadaf Ebrahimi 
6541*f5c631daSSadaf Ebrahimi   // Signed rounding shift right by immediate.
6542*f5c631daSSadaf Ebrahimi   void srshr(const ZRegister& zd,
6543*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
6544*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
6545*f5c631daSSadaf Ebrahimi              int shift);
6546*f5c631daSSadaf Ebrahimi 
6547*f5c631daSSadaf Ebrahimi   // Signed rounding shift right and accumulate (immediate).
6548*f5c631daSSadaf Ebrahimi   void srsra(const ZRegister& zda, const ZRegister& zn, int shift);
6549*f5c631daSSadaf Ebrahimi 
6550*f5c631daSSadaf Ebrahimi   // Signed shift left long by immediate (bottom).
6551*f5c631daSSadaf Ebrahimi   void sshllb(const ZRegister& zd, const ZRegister& zn, int shift);
6552*f5c631daSSadaf Ebrahimi 
6553*f5c631daSSadaf Ebrahimi   // Signed shift left long by immediate (top).
6554*f5c631daSSadaf Ebrahimi   void sshllt(const ZRegister& zd, const ZRegister& zn, int shift);
6555*f5c631daSSadaf Ebrahimi 
6556*f5c631daSSadaf Ebrahimi   // Signed shift right and accumulate (immediate).
6557*f5c631daSSadaf Ebrahimi   void ssra(const ZRegister& zda, const ZRegister& zn, int shift);
6558*f5c631daSSadaf Ebrahimi 
6559*f5c631daSSadaf Ebrahimi   // Signed subtract long (bottom).
6560*f5c631daSSadaf Ebrahimi   void ssublb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6561*f5c631daSSadaf Ebrahimi 
6562*f5c631daSSadaf Ebrahimi   // Signed subtract long (bottom - top).
6563*f5c631daSSadaf Ebrahimi   void ssublbt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6564*f5c631daSSadaf Ebrahimi 
6565*f5c631daSSadaf Ebrahimi   // Signed subtract long (top).
6566*f5c631daSSadaf Ebrahimi   void ssublt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6567*f5c631daSSadaf Ebrahimi 
6568*f5c631daSSadaf Ebrahimi   // Signed subtract long (top - bottom).
6569*f5c631daSSadaf Ebrahimi   void ssubltb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6570*f5c631daSSadaf Ebrahimi 
6571*f5c631daSSadaf Ebrahimi   // Signed subtract wide (bottom).
6572*f5c631daSSadaf Ebrahimi   void ssubwb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6573*f5c631daSSadaf Ebrahimi 
6574*f5c631daSSadaf Ebrahimi   // Signed subtract wide (top).
6575*f5c631daSSadaf Ebrahimi   void ssubwt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6576*f5c631daSSadaf Ebrahimi 
6577*f5c631daSSadaf Ebrahimi   // Subtract narrow high part (bottom).
6578*f5c631daSSadaf Ebrahimi   void subhnb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6579*f5c631daSSadaf Ebrahimi 
6580*f5c631daSSadaf Ebrahimi   // Subtract narrow high part (top).
6581*f5c631daSSadaf Ebrahimi   void subhnt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6582*f5c631daSSadaf Ebrahimi 
6583*f5c631daSSadaf Ebrahimi   // Signed saturating addition of unsigned value.
6584*f5c631daSSadaf Ebrahimi   void suqadd(const ZRegister& zd,
6585*f5c631daSSadaf Ebrahimi               const PRegisterM& pg,
6586*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6587*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
6588*f5c631daSSadaf Ebrahimi 
6589*f5c631daSSadaf Ebrahimi   // Programmable table lookup in one or two vector table (zeroing).
6590*f5c631daSSadaf Ebrahimi   void tbl(const ZRegister& zd,
6591*f5c631daSSadaf Ebrahimi            const ZRegister& zn1,
6592*f5c631daSSadaf Ebrahimi            const ZRegister& zn2,
6593*f5c631daSSadaf Ebrahimi            const ZRegister& zm);
6594*f5c631daSSadaf Ebrahimi 
6595*f5c631daSSadaf Ebrahimi   // Programmable table lookup in single vector table (merging).
6596*f5c631daSSadaf Ebrahimi   void tbx(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6597*f5c631daSSadaf Ebrahimi 
6598*f5c631daSSadaf Ebrahimi   // Unsigned absolute difference and accumulate.
6599*f5c631daSSadaf Ebrahimi   void uaba(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6600*f5c631daSSadaf Ebrahimi 
6601*f5c631daSSadaf Ebrahimi   // Unsigned absolute difference and accumulate long (bottom).
6602*f5c631daSSadaf Ebrahimi   void uabalb(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6603*f5c631daSSadaf Ebrahimi 
6604*f5c631daSSadaf Ebrahimi   // Unsigned absolute difference and accumulate long (top).
6605*f5c631daSSadaf Ebrahimi   void uabalt(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6606*f5c631daSSadaf Ebrahimi 
6607*f5c631daSSadaf Ebrahimi   // Unsigned absolute difference long (bottom).
6608*f5c631daSSadaf Ebrahimi   void uabdlb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6609*f5c631daSSadaf Ebrahimi 
6610*f5c631daSSadaf Ebrahimi   // Unsigned absolute difference long (top).
6611*f5c631daSSadaf Ebrahimi   void uabdlt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6612*f5c631daSSadaf Ebrahimi 
6613*f5c631daSSadaf Ebrahimi   // Unsigned add and accumulate long pairwise.
6614*f5c631daSSadaf Ebrahimi   void uadalp(const ZRegister& zda, const PRegisterM& pg, const ZRegister& zn);
6615*f5c631daSSadaf Ebrahimi 
6616*f5c631daSSadaf Ebrahimi   // Unsigned add long (bottom).
6617*f5c631daSSadaf Ebrahimi   void uaddlb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6618*f5c631daSSadaf Ebrahimi 
6619*f5c631daSSadaf Ebrahimi   // Unsigned add long (top).
6620*f5c631daSSadaf Ebrahimi   void uaddlt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6621*f5c631daSSadaf Ebrahimi 
6622*f5c631daSSadaf Ebrahimi   // Unsigned add wide (bottom).
6623*f5c631daSSadaf Ebrahimi   void uaddwb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6624*f5c631daSSadaf Ebrahimi 
6625*f5c631daSSadaf Ebrahimi   // Unsigned add wide (top).
6626*f5c631daSSadaf Ebrahimi   void uaddwt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6627*f5c631daSSadaf Ebrahimi 
6628*f5c631daSSadaf Ebrahimi   // Unsigned halving addition.
6629*f5c631daSSadaf Ebrahimi   void uhadd(const ZRegister& zd,
6630*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
6631*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
6632*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
6633*f5c631daSSadaf Ebrahimi 
6634*f5c631daSSadaf Ebrahimi   // Unsigned halving subtract.
6635*f5c631daSSadaf Ebrahimi   void uhsub(const ZRegister& zd,
6636*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
6637*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
6638*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
6639*f5c631daSSadaf Ebrahimi 
6640*f5c631daSSadaf Ebrahimi   // Unsigned halving subtract reversed vectors.
6641*f5c631daSSadaf Ebrahimi   void uhsubr(const ZRegister& zd,
6642*f5c631daSSadaf Ebrahimi               const PRegisterM& pg,
6643*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6644*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
6645*f5c631daSSadaf Ebrahimi 
6646*f5c631daSSadaf Ebrahimi   // Unsigned maximum pairwise.
6647*f5c631daSSadaf Ebrahimi   void umaxp(const ZRegister& zd,
6648*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
6649*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
6650*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
6651*f5c631daSSadaf Ebrahimi 
6652*f5c631daSSadaf Ebrahimi   // Unsigned minimum pairwise.
6653*f5c631daSSadaf Ebrahimi   void uminp(const ZRegister& zd,
6654*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
6655*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
6656*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
6657*f5c631daSSadaf Ebrahimi 
6658*f5c631daSSadaf Ebrahimi   // Unsigned multiply-add long to accumulator (bottom, indexed).
6659*f5c631daSSadaf Ebrahimi   void umlalb(const ZRegister& zda,
6660*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6661*f5c631daSSadaf Ebrahimi               const ZRegister& zm,
6662*f5c631daSSadaf Ebrahimi               int index);
6663*f5c631daSSadaf Ebrahimi 
6664*f5c631daSSadaf Ebrahimi   // Unsigned multiply-add long to accumulator (bottom).
6665*f5c631daSSadaf Ebrahimi   void umlalb(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6666*f5c631daSSadaf Ebrahimi 
6667*f5c631daSSadaf Ebrahimi   // Unsigned multiply-add long to accumulator (top, indexed).
6668*f5c631daSSadaf Ebrahimi   void umlalt(const ZRegister& zda,
6669*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6670*f5c631daSSadaf Ebrahimi               const ZRegister& zm,
6671*f5c631daSSadaf Ebrahimi               int index);
6672*f5c631daSSadaf Ebrahimi 
6673*f5c631daSSadaf Ebrahimi   // Unsigned multiply-add long to accumulator (top).
6674*f5c631daSSadaf Ebrahimi   void umlalt(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6675*f5c631daSSadaf Ebrahimi 
6676*f5c631daSSadaf Ebrahimi   // Unsigned multiply-subtract long from accumulator (bottom, indexed).
6677*f5c631daSSadaf Ebrahimi   void umlslb(const ZRegister& zda,
6678*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6679*f5c631daSSadaf Ebrahimi               const ZRegister& zm,
6680*f5c631daSSadaf Ebrahimi               int index);
6681*f5c631daSSadaf Ebrahimi 
6682*f5c631daSSadaf Ebrahimi   // Unsigned multiply-subtract long from accumulator (bottom).
6683*f5c631daSSadaf Ebrahimi   void umlslb(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6684*f5c631daSSadaf Ebrahimi 
6685*f5c631daSSadaf Ebrahimi   // Unsigned multiply-subtract long from accumulator (top, indexed).
6686*f5c631daSSadaf Ebrahimi   void umlslt(const ZRegister& zda,
6687*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6688*f5c631daSSadaf Ebrahimi               const ZRegister& zm,
6689*f5c631daSSadaf Ebrahimi               int index);
6690*f5c631daSSadaf Ebrahimi 
6691*f5c631daSSadaf Ebrahimi   // Unsigned multiply-subtract long from accumulator (top).
6692*f5c631daSSadaf Ebrahimi   void umlslt(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6693*f5c631daSSadaf Ebrahimi 
6694*f5c631daSSadaf Ebrahimi   // Unsigned multiply returning high half (unpredicated).
6695*f5c631daSSadaf Ebrahimi   void umulh(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6696*f5c631daSSadaf Ebrahimi 
6697*f5c631daSSadaf Ebrahimi   // Unsigned multiply long (bottom, indexed).
6698*f5c631daSSadaf Ebrahimi   void umullb(const ZRegister& zd,
6699*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6700*f5c631daSSadaf Ebrahimi               const ZRegister& zm,
6701*f5c631daSSadaf Ebrahimi               int index);
6702*f5c631daSSadaf Ebrahimi 
6703*f5c631daSSadaf Ebrahimi   // Unsigned multiply long (bottom).
6704*f5c631daSSadaf Ebrahimi   void umullb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6705*f5c631daSSadaf Ebrahimi 
6706*f5c631daSSadaf Ebrahimi   // Unsigned multiply long (top, indexed).
6707*f5c631daSSadaf Ebrahimi   void umullt(const ZRegister& zd,
6708*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6709*f5c631daSSadaf Ebrahimi               const ZRegister& zm,
6710*f5c631daSSadaf Ebrahimi               int index);
6711*f5c631daSSadaf Ebrahimi 
6712*f5c631daSSadaf Ebrahimi   // Unsigned multiply long (top).
6713*f5c631daSSadaf Ebrahimi   void umullt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6714*f5c631daSSadaf Ebrahimi 
6715*f5c631daSSadaf Ebrahimi   // Unsigned saturating addition (predicated).
6716*f5c631daSSadaf Ebrahimi   void uqadd(const ZRegister& zd,
6717*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
6718*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
6719*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
6720*f5c631daSSadaf Ebrahimi 
6721*f5c631daSSadaf Ebrahimi   // Unsigned saturating rounding shift left by vector (predicated).
6722*f5c631daSSadaf Ebrahimi   void uqrshl(const ZRegister& zd,
6723*f5c631daSSadaf Ebrahimi               const PRegisterM& pg,
6724*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6725*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
6726*f5c631daSSadaf Ebrahimi 
6727*f5c631daSSadaf Ebrahimi   // Unsigned saturating rounding shift left reversed vectors (predicated).
6728*f5c631daSSadaf Ebrahimi   void uqrshlr(const ZRegister& zd,
6729*f5c631daSSadaf Ebrahimi                const PRegisterM& pg,
6730*f5c631daSSadaf Ebrahimi                const ZRegister& zn,
6731*f5c631daSSadaf Ebrahimi                const ZRegister& zm);
6732*f5c631daSSadaf Ebrahimi 
6733*f5c631daSSadaf Ebrahimi   // Unsigned saturating rounding shift right narrow by immediate (bottom).
6734*f5c631daSSadaf Ebrahimi   void uqrshrnb(const ZRegister& zd, const ZRegister& zn, int shift);
6735*f5c631daSSadaf Ebrahimi 
6736*f5c631daSSadaf Ebrahimi   // Unsigned saturating rounding shift right narrow by immediate (top).
6737*f5c631daSSadaf Ebrahimi   void uqrshrnt(const ZRegister& zd, const ZRegister& zn, int shift);
6738*f5c631daSSadaf Ebrahimi 
6739*f5c631daSSadaf Ebrahimi   // Unsigned saturating shift left by immediate.
6740*f5c631daSSadaf Ebrahimi   void uqshl(const ZRegister& zd,
6741*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
6742*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
6743*f5c631daSSadaf Ebrahimi              int shift);
6744*f5c631daSSadaf Ebrahimi 
6745*f5c631daSSadaf Ebrahimi   // Unsigned saturating shift left by vector (predicated).
6746*f5c631daSSadaf Ebrahimi   void uqshl(const ZRegister& zd,
6747*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
6748*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
6749*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
6750*f5c631daSSadaf Ebrahimi 
6751*f5c631daSSadaf Ebrahimi   // Unsigned saturating shift left reversed vectors (predicated).
6752*f5c631daSSadaf Ebrahimi   void uqshlr(const ZRegister& zd,
6753*f5c631daSSadaf Ebrahimi               const PRegisterM& pg,
6754*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6755*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
6756*f5c631daSSadaf Ebrahimi 
6757*f5c631daSSadaf Ebrahimi   // Unsigned saturating shift right narrow by immediate (bottom).
6758*f5c631daSSadaf Ebrahimi   void uqshrnb(const ZRegister& zd, const ZRegister& zn, int shift);
6759*f5c631daSSadaf Ebrahimi 
6760*f5c631daSSadaf Ebrahimi   // Unsigned saturating shift right narrow by immediate (top).
6761*f5c631daSSadaf Ebrahimi   void uqshrnt(const ZRegister& zd, const ZRegister& zn, int shift);
6762*f5c631daSSadaf Ebrahimi 
6763*f5c631daSSadaf Ebrahimi   // Unsigned saturating subtraction (predicated).
6764*f5c631daSSadaf Ebrahimi   void uqsub(const ZRegister& zd,
6765*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
6766*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
6767*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
6768*f5c631daSSadaf Ebrahimi 
6769*f5c631daSSadaf Ebrahimi   // Unsigned saturating subtraction reversed vectors (predicated).
6770*f5c631daSSadaf Ebrahimi   void uqsubr(const ZRegister& zd,
6771*f5c631daSSadaf Ebrahimi               const PRegisterM& pg,
6772*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6773*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
6774*f5c631daSSadaf Ebrahimi 
6775*f5c631daSSadaf Ebrahimi   // Unsigned saturating extract narrow (bottom).
6776*f5c631daSSadaf Ebrahimi   void uqxtnb(const ZRegister& zd, const ZRegister& zn);
6777*f5c631daSSadaf Ebrahimi 
6778*f5c631daSSadaf Ebrahimi   // Unsigned saturating extract narrow (top).
6779*f5c631daSSadaf Ebrahimi   void uqxtnt(const ZRegister& zd, const ZRegister& zn);
6780*f5c631daSSadaf Ebrahimi 
6781*f5c631daSSadaf Ebrahimi   // Unsigned reciprocal estimate (predicated).
6782*f5c631daSSadaf Ebrahimi   void urecpe(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
6783*f5c631daSSadaf Ebrahimi 
6784*f5c631daSSadaf Ebrahimi   // Unsigned rounding halving addition.
6785*f5c631daSSadaf Ebrahimi   void urhadd(const ZRegister& zd,
6786*f5c631daSSadaf Ebrahimi               const PRegisterM& pg,
6787*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6788*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
6789*f5c631daSSadaf Ebrahimi 
6790*f5c631daSSadaf Ebrahimi   // Unsigned rounding shift left by vector (predicated).
6791*f5c631daSSadaf Ebrahimi   void urshl(const ZRegister& zd,
6792*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
6793*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
6794*f5c631daSSadaf Ebrahimi              const ZRegister& zm);
6795*f5c631daSSadaf Ebrahimi 
6796*f5c631daSSadaf Ebrahimi   // Unsigned rounding shift left reversed vectors (predicated).
6797*f5c631daSSadaf Ebrahimi   void urshlr(const ZRegister& zd,
6798*f5c631daSSadaf Ebrahimi               const PRegisterM& pg,
6799*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6800*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
6801*f5c631daSSadaf Ebrahimi 
6802*f5c631daSSadaf Ebrahimi   // Unsigned rounding shift right by immediate.
6803*f5c631daSSadaf Ebrahimi   void urshr(const ZRegister& zd,
6804*f5c631daSSadaf Ebrahimi              const PRegisterM& pg,
6805*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
6806*f5c631daSSadaf Ebrahimi              int shift);
6807*f5c631daSSadaf Ebrahimi 
6808*f5c631daSSadaf Ebrahimi   // Unsigned reciprocal square root estimate (predicated).
6809*f5c631daSSadaf Ebrahimi   void ursqrte(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn);
6810*f5c631daSSadaf Ebrahimi 
6811*f5c631daSSadaf Ebrahimi   // Unsigned rounding shift right and accumulate (immediate).
6812*f5c631daSSadaf Ebrahimi   void ursra(const ZRegister& zda, const ZRegister& zn, int shift);
6813*f5c631daSSadaf Ebrahimi 
6814*f5c631daSSadaf Ebrahimi   // Unsigned shift left long by immediate (bottom).
6815*f5c631daSSadaf Ebrahimi   void ushllb(const ZRegister& zd, const ZRegister& zn, int shift);
6816*f5c631daSSadaf Ebrahimi 
6817*f5c631daSSadaf Ebrahimi   // Unsigned shift left long by immediate (top).
6818*f5c631daSSadaf Ebrahimi   void ushllt(const ZRegister& zd, const ZRegister& zn, int shift);
6819*f5c631daSSadaf Ebrahimi 
6820*f5c631daSSadaf Ebrahimi   // Unsigned saturating addition of signed value.
6821*f5c631daSSadaf Ebrahimi   void usqadd(const ZRegister& zd,
6822*f5c631daSSadaf Ebrahimi               const PRegisterM& pg,
6823*f5c631daSSadaf Ebrahimi               const ZRegister& zn,
6824*f5c631daSSadaf Ebrahimi               const ZRegister& zm);
6825*f5c631daSSadaf Ebrahimi 
6826*f5c631daSSadaf Ebrahimi   // Unsigned shift right and accumulate (immediate).
6827*f5c631daSSadaf Ebrahimi   void usra(const ZRegister& zda, const ZRegister& zn, int shift);
6828*f5c631daSSadaf Ebrahimi 
6829*f5c631daSSadaf Ebrahimi   // Unsigned subtract long (bottom).
6830*f5c631daSSadaf Ebrahimi   void usublb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6831*f5c631daSSadaf Ebrahimi 
6832*f5c631daSSadaf Ebrahimi   // Unsigned subtract long (top).
6833*f5c631daSSadaf Ebrahimi   void usublt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6834*f5c631daSSadaf Ebrahimi 
6835*f5c631daSSadaf Ebrahimi   // Unsigned subtract wide (bottom).
6836*f5c631daSSadaf Ebrahimi   void usubwb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6837*f5c631daSSadaf Ebrahimi 
6838*f5c631daSSadaf Ebrahimi   // Unsigned subtract wide (top).
6839*f5c631daSSadaf Ebrahimi   void usubwt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm);
6840*f5c631daSSadaf Ebrahimi 
6841*f5c631daSSadaf Ebrahimi   // While decrementing signed scalar greater than or equal to scalar.
6842*f5c631daSSadaf Ebrahimi   void whilege(const PRegisterWithLaneSize& pd,
6843*f5c631daSSadaf Ebrahimi                const Register& rn,
6844*f5c631daSSadaf Ebrahimi                const Register& rm);
6845*f5c631daSSadaf Ebrahimi 
6846*f5c631daSSadaf Ebrahimi   // While decrementing signed scalar greater than scalar.
6847*f5c631daSSadaf Ebrahimi   void whilegt(const PRegisterWithLaneSize& pd,
6848*f5c631daSSadaf Ebrahimi                const Register& rn,
6849*f5c631daSSadaf Ebrahimi                const Register& rm);
6850*f5c631daSSadaf Ebrahimi 
6851*f5c631daSSadaf Ebrahimi   // While decrementing unsigned scalar higher than scalar.
6852*f5c631daSSadaf Ebrahimi   void whilehi(const PRegisterWithLaneSize& pd,
6853*f5c631daSSadaf Ebrahimi                const Register& rn,
6854*f5c631daSSadaf Ebrahimi                const Register& rm);
6855*f5c631daSSadaf Ebrahimi 
6856*f5c631daSSadaf Ebrahimi   // While decrementing unsigned scalar higher or same as scalar.
6857*f5c631daSSadaf Ebrahimi   void whilehs(const PRegisterWithLaneSize& pd,
6858*f5c631daSSadaf Ebrahimi                const Register& rn,
6859*f5c631daSSadaf Ebrahimi                const Register& rm);
6860*f5c631daSSadaf Ebrahimi 
6861*f5c631daSSadaf Ebrahimi   // While free of read-after-write conflicts.
6862*f5c631daSSadaf Ebrahimi   void whilerw(const PRegisterWithLaneSize& pd,
6863*f5c631daSSadaf Ebrahimi                const Register& rn,
6864*f5c631daSSadaf Ebrahimi                const Register& rm);
6865*f5c631daSSadaf Ebrahimi 
6866*f5c631daSSadaf Ebrahimi   // While free of write-after-read/write conflicts.
6867*f5c631daSSadaf Ebrahimi   void whilewr(const PRegisterWithLaneSize& pd,
6868*f5c631daSSadaf Ebrahimi                const Register& rn,
6869*f5c631daSSadaf Ebrahimi                const Register& rm);
6870*f5c631daSSadaf Ebrahimi 
6871*f5c631daSSadaf Ebrahimi   // Bitwise exclusive OR and rotate right by immediate.
6872*f5c631daSSadaf Ebrahimi   void xar(const ZRegister& zd,
6873*f5c631daSSadaf Ebrahimi            const ZRegister& zn,
6874*f5c631daSSadaf Ebrahimi            const ZRegister& zm,
6875*f5c631daSSadaf Ebrahimi            int shift);
6876*f5c631daSSadaf Ebrahimi 
6877*f5c631daSSadaf Ebrahimi   // Floating-point matrix multiply-accumulate.
6878*f5c631daSSadaf Ebrahimi   void fmmla(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6879*f5c631daSSadaf Ebrahimi 
6880*f5c631daSSadaf Ebrahimi   // Signed integer matrix multiply-accumulate.
6881*f5c631daSSadaf Ebrahimi   void smmla(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6882*f5c631daSSadaf Ebrahimi 
6883*f5c631daSSadaf Ebrahimi   // Unsigned by signed integer matrix multiply-accumulate.
6884*f5c631daSSadaf Ebrahimi   void usmmla(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6885*f5c631daSSadaf Ebrahimi 
6886*f5c631daSSadaf Ebrahimi   // Unsigned integer matrix multiply-accumulate.
6887*f5c631daSSadaf Ebrahimi   void ummla(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6888*f5c631daSSadaf Ebrahimi 
6889*f5c631daSSadaf Ebrahimi   // Unsigned by signed integer dot product.
6890*f5c631daSSadaf Ebrahimi   void usdot(const ZRegister& zda, const ZRegister& zn, const ZRegister& zm);
6891*f5c631daSSadaf Ebrahimi 
6892*f5c631daSSadaf Ebrahimi   // Unsigned by signed integer indexed dot product.
6893*f5c631daSSadaf Ebrahimi   void usdot(const ZRegister& zda,
6894*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
6895*f5c631daSSadaf Ebrahimi              const ZRegister& zm,
6896*f5c631daSSadaf Ebrahimi              int index);
6897*f5c631daSSadaf Ebrahimi 
6898*f5c631daSSadaf Ebrahimi   // Signed by unsigned integer indexed dot product.
6899*f5c631daSSadaf Ebrahimi   void sudot(const ZRegister& zda,
6900*f5c631daSSadaf Ebrahimi              const ZRegister& zn,
6901*f5c631daSSadaf Ebrahimi              const ZRegister& zm,
6902*f5c631daSSadaf Ebrahimi              int index);
6903*f5c631daSSadaf Ebrahimi 
6904*f5c631daSSadaf Ebrahimi   // Emit generic instructions.
6905*f5c631daSSadaf Ebrahimi 
6906*f5c631daSSadaf Ebrahimi   // Emit raw instructions into the instruction stream.
dci(Instr raw_inst)6907*f5c631daSSadaf Ebrahimi   void dci(Instr raw_inst) { Emit(raw_inst); }
6908*f5c631daSSadaf Ebrahimi 
6909*f5c631daSSadaf Ebrahimi   // Emit 32 bits of data into the instruction stream.
dc32(uint32_t data)6910*f5c631daSSadaf Ebrahimi   void dc32(uint32_t data) { dc(data); }
6911*f5c631daSSadaf Ebrahimi 
6912*f5c631daSSadaf Ebrahimi   // Emit 64 bits of data into the instruction stream.
dc64(uint64_t data)6913*f5c631daSSadaf Ebrahimi   void dc64(uint64_t data) { dc(data); }
6914*f5c631daSSadaf Ebrahimi 
6915*f5c631daSSadaf Ebrahimi   // Emit data in the instruction stream.
6916*f5c631daSSadaf Ebrahimi   template <typename T>
dc(T data)6917*f5c631daSSadaf Ebrahimi   void dc(T data) {
6918*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(AllowAssembler());
6919*f5c631daSSadaf Ebrahimi     GetBuffer()->Emit<T>(data);
6920*f5c631daSSadaf Ebrahimi   }
6921*f5c631daSSadaf Ebrahimi 
6922*f5c631daSSadaf Ebrahimi   // Copy a string into the instruction stream, including the terminating NULL
6923*f5c631daSSadaf Ebrahimi   // character. The instruction pointer is then aligned correctly for
6924*f5c631daSSadaf Ebrahimi   // subsequent instructions.
EmitString(const char * string)6925*f5c631daSSadaf Ebrahimi   void EmitString(const char* string) {
6926*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(string != NULL);
6927*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(AllowAssembler());
6928*f5c631daSSadaf Ebrahimi 
6929*f5c631daSSadaf Ebrahimi     GetBuffer()->EmitString(string);
6930*f5c631daSSadaf Ebrahimi     GetBuffer()->Align();
6931*f5c631daSSadaf Ebrahimi   }
6932*f5c631daSSadaf Ebrahimi 
6933*f5c631daSSadaf Ebrahimi   // Code generation helpers.
6934*f5c631daSSadaf Ebrahimi   static bool OneInstrMoveImmediateHelper(Assembler* assm,
6935*f5c631daSSadaf Ebrahimi                                           const Register& dst,
6936*f5c631daSSadaf Ebrahimi                                           uint64_t imm);
6937*f5c631daSSadaf Ebrahimi 
6938*f5c631daSSadaf Ebrahimi   // Register encoding.
6939*f5c631daSSadaf Ebrahimi   template <int hibit, int lobit>
Rx(CPURegister rx)6940*f5c631daSSadaf Ebrahimi   static Instr Rx(CPURegister rx) {
6941*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(rx.GetCode() != kSPRegInternalCode);
6942*f5c631daSSadaf Ebrahimi     return ImmUnsignedField<hibit, lobit>(rx.GetCode());
6943*f5c631daSSadaf Ebrahimi   }
6944*f5c631daSSadaf Ebrahimi 
6945*f5c631daSSadaf Ebrahimi #define CPU_REGISTER_FIELD_NAMES(V) V(d) V(n) V(m) V(a) V(t) V(t2) V(s)
6946*f5c631daSSadaf Ebrahimi #define REGISTER_ENCODER(N)                                           \
6947*f5c631daSSadaf Ebrahimi   static Instr R##N(CPURegister r##N) {                               \
6948*f5c631daSSadaf Ebrahimi     return Rx<R##N##_offset + R##N##_width - 1, R##N##_offset>(r##N); \
6949*f5c631daSSadaf Ebrahimi   }
CPU_REGISTER_FIELD_NAMES(REGISTER_ENCODER)6950*f5c631daSSadaf Ebrahimi   CPU_REGISTER_FIELD_NAMES(REGISTER_ENCODER)
6951*f5c631daSSadaf Ebrahimi #undef REGISTER_ENCODER
6952*f5c631daSSadaf Ebrahimi #undef CPU_REGISTER_FIELD_NAMES
6953*f5c631daSSadaf Ebrahimi 
6954*f5c631daSSadaf Ebrahimi   static Instr RmNot31(CPURegister rm) {
6955*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(rm.GetCode() != kSPRegInternalCode);
6956*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(!rm.IsZero());
6957*f5c631daSSadaf Ebrahimi     return Rm(rm);
6958*f5c631daSSadaf Ebrahimi   }
6959*f5c631daSSadaf Ebrahimi 
6960*f5c631daSSadaf Ebrahimi   // These encoding functions allow the stack pointer to be encoded, and
6961*f5c631daSSadaf Ebrahimi   // disallow the zero register.
RdSP(Register rd)6962*f5c631daSSadaf Ebrahimi   static Instr RdSP(Register rd) {
6963*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(!rd.IsZero());
6964*f5c631daSSadaf Ebrahimi     return (rd.GetCode() & kRegCodeMask) << Rd_offset;
6965*f5c631daSSadaf Ebrahimi   }
6966*f5c631daSSadaf Ebrahimi 
RnSP(Register rn)6967*f5c631daSSadaf Ebrahimi   static Instr RnSP(Register rn) {
6968*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(!rn.IsZero());
6969*f5c631daSSadaf Ebrahimi     return (rn.GetCode() & kRegCodeMask) << Rn_offset;
6970*f5c631daSSadaf Ebrahimi   }
6971*f5c631daSSadaf Ebrahimi 
RmSP(Register rm)6972*f5c631daSSadaf Ebrahimi   static Instr RmSP(Register rm) {
6973*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(!rm.IsZero());
6974*f5c631daSSadaf Ebrahimi     return (rm.GetCode() & kRegCodeMask) << Rm_offset;
6975*f5c631daSSadaf Ebrahimi   }
6976*f5c631daSSadaf Ebrahimi 
Pd(PRegister pd)6977*f5c631daSSadaf Ebrahimi   static Instr Pd(PRegister pd) {
6978*f5c631daSSadaf Ebrahimi     return Rx<Pd_offset + Pd_width - 1, Pd_offset>(pd);
6979*f5c631daSSadaf Ebrahimi   }
6980*f5c631daSSadaf Ebrahimi 
Pm(PRegister pm)6981*f5c631daSSadaf Ebrahimi   static Instr Pm(PRegister pm) {
6982*f5c631daSSadaf Ebrahimi     return Rx<Pm_offset + Pm_width - 1, Pm_offset>(pm);
6983*f5c631daSSadaf Ebrahimi   }
6984*f5c631daSSadaf Ebrahimi 
Pn(PRegister pn)6985*f5c631daSSadaf Ebrahimi   static Instr Pn(PRegister pn) {
6986*f5c631daSSadaf Ebrahimi     return Rx<Pn_offset + Pn_width - 1, Pn_offset>(pn);
6987*f5c631daSSadaf Ebrahimi   }
6988*f5c631daSSadaf Ebrahimi 
PgLow8(PRegister pg)6989*f5c631daSSadaf Ebrahimi   static Instr PgLow8(PRegister pg) {
6990*f5c631daSSadaf Ebrahimi     // Governing predicates can be merging, zeroing, or unqualified. They should
6991*f5c631daSSadaf Ebrahimi     // never have a lane size.
6992*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(!pg.HasLaneSize());
6993*f5c631daSSadaf Ebrahimi     return Rx<PgLow8_offset + PgLow8_width - 1, PgLow8_offset>(pg);
6994*f5c631daSSadaf Ebrahimi   }
6995*f5c631daSSadaf Ebrahimi 
6996*f5c631daSSadaf Ebrahimi   template <int hibit, int lobit>
Pg(PRegister pg)6997*f5c631daSSadaf Ebrahimi   static Instr Pg(PRegister pg) {
6998*f5c631daSSadaf Ebrahimi     // Governing predicates can be merging, zeroing, or unqualified. They should
6999*f5c631daSSadaf Ebrahimi     // never have a lane size.
7000*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(!pg.HasLaneSize());
7001*f5c631daSSadaf Ebrahimi     return Rx<hibit, lobit>(pg);
7002*f5c631daSSadaf Ebrahimi   }
7003*f5c631daSSadaf Ebrahimi 
7004*f5c631daSSadaf Ebrahimi   // Flags encoding.
Flags(FlagsUpdate S)7005*f5c631daSSadaf Ebrahimi   static Instr Flags(FlagsUpdate S) {
7006*f5c631daSSadaf Ebrahimi     if (S == SetFlags) {
7007*f5c631daSSadaf Ebrahimi       return 1 << FlagsUpdate_offset;
7008*f5c631daSSadaf Ebrahimi     } else if (S == LeaveFlags) {
7009*f5c631daSSadaf Ebrahimi       return 0 << FlagsUpdate_offset;
7010*f5c631daSSadaf Ebrahimi     }
7011*f5c631daSSadaf Ebrahimi     VIXL_UNREACHABLE();
7012*f5c631daSSadaf Ebrahimi     return 0;
7013*f5c631daSSadaf Ebrahimi   }
7014*f5c631daSSadaf Ebrahimi 
Cond(Condition cond)7015*f5c631daSSadaf Ebrahimi   static Instr Cond(Condition cond) { return cond << Condition_offset; }
7016*f5c631daSSadaf Ebrahimi 
7017*f5c631daSSadaf Ebrahimi   // Generic immediate encoding.
7018*f5c631daSSadaf Ebrahimi   template <int hibit, int lobit>
ImmField(int64_t imm)7019*f5c631daSSadaf Ebrahimi   static Instr ImmField(int64_t imm) {
7020*f5c631daSSadaf Ebrahimi     VIXL_STATIC_ASSERT((hibit >= lobit) && (lobit >= 0));
7021*f5c631daSSadaf Ebrahimi     VIXL_STATIC_ASSERT(hibit < (sizeof(Instr) * kBitsPerByte));
7022*f5c631daSSadaf Ebrahimi     int fieldsize = hibit - lobit + 1;
7023*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsIntN(fieldsize, imm));
7024*f5c631daSSadaf Ebrahimi     return static_cast<Instr>(TruncateToUintN(fieldsize, imm) << lobit);
7025*f5c631daSSadaf Ebrahimi   }
7026*f5c631daSSadaf Ebrahimi 
7027*f5c631daSSadaf Ebrahimi   // For unsigned immediate encoding.
7028*f5c631daSSadaf Ebrahimi   // TODO: Handle signed and unsigned immediate in satisfactory way.
7029*f5c631daSSadaf Ebrahimi   template <int hibit, int lobit>
ImmUnsignedField(uint64_t imm)7030*f5c631daSSadaf Ebrahimi   static Instr ImmUnsignedField(uint64_t imm) {
7031*f5c631daSSadaf Ebrahimi     VIXL_STATIC_ASSERT((hibit >= lobit) && (lobit >= 0));
7032*f5c631daSSadaf Ebrahimi     VIXL_STATIC_ASSERT(hibit < (sizeof(Instr) * kBitsPerByte));
7033*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUintN(hibit - lobit + 1, imm));
7034*f5c631daSSadaf Ebrahimi     return static_cast<Instr>(imm << lobit);
7035*f5c631daSSadaf Ebrahimi   }
7036*f5c631daSSadaf Ebrahimi 
7037*f5c631daSSadaf Ebrahimi   // PC-relative address encoding.
ImmPCRelAddress(int64_t imm21)7038*f5c631daSSadaf Ebrahimi   static Instr ImmPCRelAddress(int64_t imm21) {
7039*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsInt21(imm21));
7040*f5c631daSSadaf Ebrahimi     Instr imm = static_cast<Instr>(TruncateToUint21(imm21));
7041*f5c631daSSadaf Ebrahimi     Instr immhi = (imm >> ImmPCRelLo_width) << ImmPCRelHi_offset;
7042*f5c631daSSadaf Ebrahimi     Instr immlo = imm << ImmPCRelLo_offset;
7043*f5c631daSSadaf Ebrahimi     return (immhi & ImmPCRelHi_mask) | (immlo & ImmPCRelLo_mask);
7044*f5c631daSSadaf Ebrahimi   }
7045*f5c631daSSadaf Ebrahimi 
7046*f5c631daSSadaf Ebrahimi   // Branch encoding.
ImmUncondBranch(int64_t imm26)7047*f5c631daSSadaf Ebrahimi   static Instr ImmUncondBranch(int64_t imm26) {
7048*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsInt26(imm26));
7049*f5c631daSSadaf Ebrahimi     return TruncateToUint26(imm26) << ImmUncondBranch_offset;
7050*f5c631daSSadaf Ebrahimi   }
7051*f5c631daSSadaf Ebrahimi 
ImmCondBranch(int64_t imm19)7052*f5c631daSSadaf Ebrahimi   static Instr ImmCondBranch(int64_t imm19) {
7053*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsInt19(imm19));
7054*f5c631daSSadaf Ebrahimi     return TruncateToUint19(imm19) << ImmCondBranch_offset;
7055*f5c631daSSadaf Ebrahimi   }
7056*f5c631daSSadaf Ebrahimi 
ImmCmpBranch(int64_t imm19)7057*f5c631daSSadaf Ebrahimi   static Instr ImmCmpBranch(int64_t imm19) {
7058*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsInt19(imm19));
7059*f5c631daSSadaf Ebrahimi     return TruncateToUint19(imm19) << ImmCmpBranch_offset;
7060*f5c631daSSadaf Ebrahimi   }
7061*f5c631daSSadaf Ebrahimi 
ImmTestBranch(int64_t imm14)7062*f5c631daSSadaf Ebrahimi   static Instr ImmTestBranch(int64_t imm14) {
7063*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsInt14(imm14));
7064*f5c631daSSadaf Ebrahimi     return TruncateToUint14(imm14) << ImmTestBranch_offset;
7065*f5c631daSSadaf Ebrahimi   }
7066*f5c631daSSadaf Ebrahimi 
ImmTestBranchBit(unsigned bit_pos)7067*f5c631daSSadaf Ebrahimi   static Instr ImmTestBranchBit(unsigned bit_pos) {
7068*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint6(bit_pos));
7069*f5c631daSSadaf Ebrahimi     // Subtract five from the shift offset, as we need bit 5 from bit_pos.
7070*f5c631daSSadaf Ebrahimi     unsigned bit5 = bit_pos << (ImmTestBranchBit5_offset - 5);
7071*f5c631daSSadaf Ebrahimi     unsigned bit40 = bit_pos << ImmTestBranchBit40_offset;
7072*f5c631daSSadaf Ebrahimi     bit5 &= ImmTestBranchBit5_mask;
7073*f5c631daSSadaf Ebrahimi     bit40 &= ImmTestBranchBit40_mask;
7074*f5c631daSSadaf Ebrahimi     return bit5 | bit40;
7075*f5c631daSSadaf Ebrahimi   }
7076*f5c631daSSadaf Ebrahimi 
7077*f5c631daSSadaf Ebrahimi   // Data Processing encoding.
SF(Register rd)7078*f5c631daSSadaf Ebrahimi   static Instr SF(Register rd) {
7079*f5c631daSSadaf Ebrahimi     return rd.Is64Bits() ? SixtyFourBits : ThirtyTwoBits;
7080*f5c631daSSadaf Ebrahimi   }
7081*f5c631daSSadaf Ebrahimi 
ImmAddSub(int imm)7082*f5c631daSSadaf Ebrahimi   static Instr ImmAddSub(int imm) {
7083*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsImmAddSub(imm));
7084*f5c631daSSadaf Ebrahimi     if (IsUint12(imm)) {  // No shift required.
7085*f5c631daSSadaf Ebrahimi       imm <<= ImmAddSub_offset;
7086*f5c631daSSadaf Ebrahimi     } else {
7087*f5c631daSSadaf Ebrahimi       imm = ((imm >> 12) << ImmAddSub_offset) | (1 << ImmAddSubShift_offset);
7088*f5c631daSSadaf Ebrahimi     }
7089*f5c631daSSadaf Ebrahimi     return imm;
7090*f5c631daSSadaf Ebrahimi   }
7091*f5c631daSSadaf Ebrahimi 
SVEImmSetBits(unsigned imms,unsigned lane_size)7092*f5c631daSSadaf Ebrahimi   static Instr SVEImmSetBits(unsigned imms, unsigned lane_size) {
7093*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint6(imms));
7094*f5c631daSSadaf Ebrahimi     VIXL_ASSERT((lane_size == kDRegSize) || IsUint6(imms + 3));
7095*f5c631daSSadaf Ebrahimi     USE(lane_size);
7096*f5c631daSSadaf Ebrahimi     return imms << SVEImmSetBits_offset;
7097*f5c631daSSadaf Ebrahimi   }
7098*f5c631daSSadaf Ebrahimi 
SVEImmRotate(unsigned immr,unsigned lane_size)7099*f5c631daSSadaf Ebrahimi   static Instr SVEImmRotate(unsigned immr, unsigned lane_size) {
7100*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUintN(WhichPowerOf2(lane_size), immr));
7101*f5c631daSSadaf Ebrahimi     USE(lane_size);
7102*f5c631daSSadaf Ebrahimi     return immr << SVEImmRotate_offset;
7103*f5c631daSSadaf Ebrahimi   }
7104*f5c631daSSadaf Ebrahimi 
SVEBitN(unsigned bitn)7105*f5c631daSSadaf Ebrahimi   static Instr SVEBitN(unsigned bitn) {
7106*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint1(bitn));
7107*f5c631daSSadaf Ebrahimi     return bitn << SVEBitN_offset;
7108*f5c631daSSadaf Ebrahimi   }
7109*f5c631daSSadaf Ebrahimi 
7110*f5c631daSSadaf Ebrahimi   static Instr SVEDtype(unsigned msize_in_bytes_log2,
7111*f5c631daSSadaf Ebrahimi                         unsigned esize_in_bytes_log2,
7112*f5c631daSSadaf Ebrahimi                         bool is_signed,
7113*f5c631daSSadaf Ebrahimi                         int dtype_h_lsb = 23,
7114*f5c631daSSadaf Ebrahimi                         int dtype_l_lsb = 21) {
7115*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(msize_in_bytes_log2 <= kDRegSizeInBytesLog2);
7116*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(esize_in_bytes_log2 <= kDRegSizeInBytesLog2);
7117*f5c631daSSadaf Ebrahimi     Instr dtype_h = msize_in_bytes_log2;
7118*f5c631daSSadaf Ebrahimi     Instr dtype_l = esize_in_bytes_log2;
7119*f5c631daSSadaf Ebrahimi     // Signed forms use the encodings where msize would be greater than esize.
7120*f5c631daSSadaf Ebrahimi     if (is_signed) {
7121*f5c631daSSadaf Ebrahimi       dtype_h = dtype_h ^ 0x3;
7122*f5c631daSSadaf Ebrahimi       dtype_l = dtype_l ^ 0x3;
7123*f5c631daSSadaf Ebrahimi     }
7124*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint2(dtype_h));
7125*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint2(dtype_l));
7126*f5c631daSSadaf Ebrahimi     VIXL_ASSERT((dtype_h > dtype_l) == is_signed);
7127*f5c631daSSadaf Ebrahimi 
7128*f5c631daSSadaf Ebrahimi     return (dtype_h << dtype_h_lsb) | (dtype_l << dtype_l_lsb);
7129*f5c631daSSadaf Ebrahimi   }
7130*f5c631daSSadaf Ebrahimi 
SVEDtypeSplit(unsigned msize_in_bytes_log2,unsigned esize_in_bytes_log2,bool is_signed)7131*f5c631daSSadaf Ebrahimi   static Instr SVEDtypeSplit(unsigned msize_in_bytes_log2,
7132*f5c631daSSadaf Ebrahimi                              unsigned esize_in_bytes_log2,
7133*f5c631daSSadaf Ebrahimi                              bool is_signed) {
7134*f5c631daSSadaf Ebrahimi     return SVEDtype(msize_in_bytes_log2,
7135*f5c631daSSadaf Ebrahimi                     esize_in_bytes_log2,
7136*f5c631daSSadaf Ebrahimi                     is_signed,
7137*f5c631daSSadaf Ebrahimi                     23,
7138*f5c631daSSadaf Ebrahimi                     13);
7139*f5c631daSSadaf Ebrahimi   }
7140*f5c631daSSadaf Ebrahimi 
ImmS(unsigned imms,unsigned reg_size)7141*f5c631daSSadaf Ebrahimi   static Instr ImmS(unsigned imms, unsigned reg_size) {
7142*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(((reg_size == kXRegSize) && IsUint6(imms)) ||
7143*f5c631daSSadaf Ebrahimi                 ((reg_size == kWRegSize) && IsUint5(imms)));
7144*f5c631daSSadaf Ebrahimi     USE(reg_size);
7145*f5c631daSSadaf Ebrahimi     return imms << ImmS_offset;
7146*f5c631daSSadaf Ebrahimi   }
7147*f5c631daSSadaf Ebrahimi 
ImmR(unsigned immr,unsigned reg_size)7148*f5c631daSSadaf Ebrahimi   static Instr ImmR(unsigned immr, unsigned reg_size) {
7149*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(((reg_size == kXRegSize) && IsUint6(immr)) ||
7150*f5c631daSSadaf Ebrahimi                 ((reg_size == kWRegSize) && IsUint5(immr)));
7151*f5c631daSSadaf Ebrahimi     USE(reg_size);
7152*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint6(immr));
7153*f5c631daSSadaf Ebrahimi     return immr << ImmR_offset;
7154*f5c631daSSadaf Ebrahimi   }
7155*f5c631daSSadaf Ebrahimi 
ImmSetBits(unsigned imms,unsigned reg_size)7156*f5c631daSSadaf Ebrahimi   static Instr ImmSetBits(unsigned imms, unsigned reg_size) {
7157*f5c631daSSadaf Ebrahimi     VIXL_ASSERT((reg_size == kWRegSize) || (reg_size == kXRegSize));
7158*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint6(imms));
7159*f5c631daSSadaf Ebrahimi     VIXL_ASSERT((reg_size == kXRegSize) || IsUint6(imms + 3));
7160*f5c631daSSadaf Ebrahimi     USE(reg_size);
7161*f5c631daSSadaf Ebrahimi     return imms << ImmSetBits_offset;
7162*f5c631daSSadaf Ebrahimi   }
7163*f5c631daSSadaf Ebrahimi 
ImmRotate(unsigned immr,unsigned reg_size)7164*f5c631daSSadaf Ebrahimi   static Instr ImmRotate(unsigned immr, unsigned reg_size) {
7165*f5c631daSSadaf Ebrahimi     VIXL_ASSERT((reg_size == kWRegSize) || (reg_size == kXRegSize));
7166*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(((reg_size == kXRegSize) && IsUint6(immr)) ||
7167*f5c631daSSadaf Ebrahimi                 ((reg_size == kWRegSize) && IsUint5(immr)));
7168*f5c631daSSadaf Ebrahimi     USE(reg_size);
7169*f5c631daSSadaf Ebrahimi     return immr << ImmRotate_offset;
7170*f5c631daSSadaf Ebrahimi   }
7171*f5c631daSSadaf Ebrahimi 
ImmLLiteral(int64_t imm19)7172*f5c631daSSadaf Ebrahimi   static Instr ImmLLiteral(int64_t imm19) {
7173*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsInt19(imm19));
7174*f5c631daSSadaf Ebrahimi     return TruncateToUint19(imm19) << ImmLLiteral_offset;
7175*f5c631daSSadaf Ebrahimi   }
7176*f5c631daSSadaf Ebrahimi 
BitN(unsigned bitn,unsigned reg_size)7177*f5c631daSSadaf Ebrahimi   static Instr BitN(unsigned bitn, unsigned reg_size) {
7178*f5c631daSSadaf Ebrahimi     VIXL_ASSERT((reg_size == kWRegSize) || (reg_size == kXRegSize));
7179*f5c631daSSadaf Ebrahimi     VIXL_ASSERT((reg_size == kXRegSize) || (bitn == 0));
7180*f5c631daSSadaf Ebrahimi     USE(reg_size);
7181*f5c631daSSadaf Ebrahimi     return bitn << BitN_offset;
7182*f5c631daSSadaf Ebrahimi   }
7183*f5c631daSSadaf Ebrahimi 
ShiftDP(Shift shift)7184*f5c631daSSadaf Ebrahimi   static Instr ShiftDP(Shift shift) {
7185*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(shift == LSL || shift == LSR || shift == ASR || shift == ROR);
7186*f5c631daSSadaf Ebrahimi     return shift << ShiftDP_offset;
7187*f5c631daSSadaf Ebrahimi   }
7188*f5c631daSSadaf Ebrahimi 
ImmDPShift(unsigned amount)7189*f5c631daSSadaf Ebrahimi   static Instr ImmDPShift(unsigned amount) {
7190*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint6(amount));
7191*f5c631daSSadaf Ebrahimi     return amount << ImmDPShift_offset;
7192*f5c631daSSadaf Ebrahimi   }
7193*f5c631daSSadaf Ebrahimi 
ExtendMode(Extend extend)7194*f5c631daSSadaf Ebrahimi   static Instr ExtendMode(Extend extend) { return extend << ExtendMode_offset; }
7195*f5c631daSSadaf Ebrahimi 
ImmExtendShift(unsigned left_shift)7196*f5c631daSSadaf Ebrahimi   static Instr ImmExtendShift(unsigned left_shift) {
7197*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(left_shift <= 4);
7198*f5c631daSSadaf Ebrahimi     return left_shift << ImmExtendShift_offset;
7199*f5c631daSSadaf Ebrahimi   }
7200*f5c631daSSadaf Ebrahimi 
ImmCondCmp(unsigned imm)7201*f5c631daSSadaf Ebrahimi   static Instr ImmCondCmp(unsigned imm) {
7202*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint5(imm));
7203*f5c631daSSadaf Ebrahimi     return imm << ImmCondCmp_offset;
7204*f5c631daSSadaf Ebrahimi   }
7205*f5c631daSSadaf Ebrahimi 
Nzcv(StatusFlags nzcv)7206*f5c631daSSadaf Ebrahimi   static Instr Nzcv(StatusFlags nzcv) {
7207*f5c631daSSadaf Ebrahimi     return ((nzcv >> Flags_offset) & 0xf) << Nzcv_offset;
7208*f5c631daSSadaf Ebrahimi   }
7209*f5c631daSSadaf Ebrahimi 
7210*f5c631daSSadaf Ebrahimi   // MemOperand offset encoding.
ImmLSUnsigned(int64_t imm12)7211*f5c631daSSadaf Ebrahimi   static Instr ImmLSUnsigned(int64_t imm12) {
7212*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint12(imm12));
7213*f5c631daSSadaf Ebrahimi     return TruncateToUint12(imm12) << ImmLSUnsigned_offset;
7214*f5c631daSSadaf Ebrahimi   }
7215*f5c631daSSadaf Ebrahimi 
ImmLS(int64_t imm9)7216*f5c631daSSadaf Ebrahimi   static Instr ImmLS(int64_t imm9) {
7217*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsInt9(imm9));
7218*f5c631daSSadaf Ebrahimi     return TruncateToUint9(imm9) << ImmLS_offset;
7219*f5c631daSSadaf Ebrahimi   }
7220*f5c631daSSadaf Ebrahimi 
ImmLSPair(int64_t imm7,unsigned access_size_in_bytes_log2)7221*f5c631daSSadaf Ebrahimi   static Instr ImmLSPair(int64_t imm7, unsigned access_size_in_bytes_log2) {
7222*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsMultiple(imm7, 1 << access_size_in_bytes_log2));
7223*f5c631daSSadaf Ebrahimi     int64_t scaled_imm7 = imm7 / (1 << access_size_in_bytes_log2);
7224*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsInt7(scaled_imm7));
7225*f5c631daSSadaf Ebrahimi     return TruncateToUint7(scaled_imm7) << ImmLSPair_offset;
7226*f5c631daSSadaf Ebrahimi   }
7227*f5c631daSSadaf Ebrahimi 
ImmShiftLS(unsigned shift_amount)7228*f5c631daSSadaf Ebrahimi   static Instr ImmShiftLS(unsigned shift_amount) {
7229*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint1(shift_amount));
7230*f5c631daSSadaf Ebrahimi     return shift_amount << ImmShiftLS_offset;
7231*f5c631daSSadaf Ebrahimi   }
7232*f5c631daSSadaf Ebrahimi 
ImmLSPAC(int64_t imm10)7233*f5c631daSSadaf Ebrahimi   static Instr ImmLSPAC(int64_t imm10) {
7234*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsMultiple(imm10, 1 << 3));
7235*f5c631daSSadaf Ebrahimi     int64_t scaled_imm10 = imm10 / (1 << 3);
7236*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsInt10(scaled_imm10));
7237*f5c631daSSadaf Ebrahimi     uint32_t s_bit = (scaled_imm10 >> 9) & 1;
7238*f5c631daSSadaf Ebrahimi     return (s_bit << ImmLSPACHi_offset) |
7239*f5c631daSSadaf Ebrahimi            (TruncateToUint9(scaled_imm10) << ImmLSPACLo_offset);
7240*f5c631daSSadaf Ebrahimi   }
7241*f5c631daSSadaf Ebrahimi 
ImmPrefetchOperation(int imm5)7242*f5c631daSSadaf Ebrahimi   static Instr ImmPrefetchOperation(int imm5) {
7243*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint5(imm5));
7244*f5c631daSSadaf Ebrahimi     return imm5 << ImmPrefetchOperation_offset;
7245*f5c631daSSadaf Ebrahimi   }
7246*f5c631daSSadaf Ebrahimi 
ImmException(int imm16)7247*f5c631daSSadaf Ebrahimi   static Instr ImmException(int imm16) {
7248*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint16(imm16));
7249*f5c631daSSadaf Ebrahimi     return imm16 << ImmException_offset;
7250*f5c631daSSadaf Ebrahimi   }
7251*f5c631daSSadaf Ebrahimi 
ImmUdf(int imm16)7252*f5c631daSSadaf Ebrahimi   static Instr ImmUdf(int imm16) {
7253*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint16(imm16));
7254*f5c631daSSadaf Ebrahimi     return imm16 << ImmUdf_offset;
7255*f5c631daSSadaf Ebrahimi   }
7256*f5c631daSSadaf Ebrahimi 
ImmSystemRegister(int imm16)7257*f5c631daSSadaf Ebrahimi   static Instr ImmSystemRegister(int imm16) {
7258*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint16(imm16));
7259*f5c631daSSadaf Ebrahimi     return imm16 << ImmSystemRegister_offset;
7260*f5c631daSSadaf Ebrahimi   }
7261*f5c631daSSadaf Ebrahimi 
ImmRMIFRotation(int imm6)7262*f5c631daSSadaf Ebrahimi   static Instr ImmRMIFRotation(int imm6) {
7263*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint6(imm6));
7264*f5c631daSSadaf Ebrahimi     return imm6 << ImmRMIFRotation_offset;
7265*f5c631daSSadaf Ebrahimi   }
7266*f5c631daSSadaf Ebrahimi 
ImmHint(int imm7)7267*f5c631daSSadaf Ebrahimi   static Instr ImmHint(int imm7) {
7268*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint7(imm7));
7269*f5c631daSSadaf Ebrahimi     return imm7 << ImmHint_offset;
7270*f5c631daSSadaf Ebrahimi   }
7271*f5c631daSSadaf Ebrahimi 
CRm(int imm4)7272*f5c631daSSadaf Ebrahimi   static Instr CRm(int imm4) {
7273*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint4(imm4));
7274*f5c631daSSadaf Ebrahimi     return imm4 << CRm_offset;
7275*f5c631daSSadaf Ebrahimi   }
7276*f5c631daSSadaf Ebrahimi 
CRn(int imm4)7277*f5c631daSSadaf Ebrahimi   static Instr CRn(int imm4) {
7278*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint4(imm4));
7279*f5c631daSSadaf Ebrahimi     return imm4 << CRn_offset;
7280*f5c631daSSadaf Ebrahimi   }
7281*f5c631daSSadaf Ebrahimi 
SysOp(int imm14)7282*f5c631daSSadaf Ebrahimi   static Instr SysOp(int imm14) {
7283*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint14(imm14));
7284*f5c631daSSadaf Ebrahimi     return imm14 << SysOp_offset;
7285*f5c631daSSadaf Ebrahimi   }
7286*f5c631daSSadaf Ebrahimi 
ImmSysOp1(int imm3)7287*f5c631daSSadaf Ebrahimi   static Instr ImmSysOp1(int imm3) {
7288*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint3(imm3));
7289*f5c631daSSadaf Ebrahimi     return imm3 << SysOp1_offset;
7290*f5c631daSSadaf Ebrahimi   }
7291*f5c631daSSadaf Ebrahimi 
ImmSysOp2(int imm3)7292*f5c631daSSadaf Ebrahimi   static Instr ImmSysOp2(int imm3) {
7293*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint3(imm3));
7294*f5c631daSSadaf Ebrahimi     return imm3 << SysOp2_offset;
7295*f5c631daSSadaf Ebrahimi   }
7296*f5c631daSSadaf Ebrahimi 
ImmBarrierDomain(int imm2)7297*f5c631daSSadaf Ebrahimi   static Instr ImmBarrierDomain(int imm2) {
7298*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint2(imm2));
7299*f5c631daSSadaf Ebrahimi     return imm2 << ImmBarrierDomain_offset;
7300*f5c631daSSadaf Ebrahimi   }
7301*f5c631daSSadaf Ebrahimi 
ImmBarrierType(int imm2)7302*f5c631daSSadaf Ebrahimi   static Instr ImmBarrierType(int imm2) {
7303*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint2(imm2));
7304*f5c631daSSadaf Ebrahimi     return imm2 << ImmBarrierType_offset;
7305*f5c631daSSadaf Ebrahimi   }
7306*f5c631daSSadaf Ebrahimi 
7307*f5c631daSSadaf Ebrahimi   // Move immediates encoding.
ImmMoveWide(uint64_t imm)7308*f5c631daSSadaf Ebrahimi   static Instr ImmMoveWide(uint64_t imm) {
7309*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint16(imm));
7310*f5c631daSSadaf Ebrahimi     return static_cast<Instr>(imm << ImmMoveWide_offset);
7311*f5c631daSSadaf Ebrahimi   }
7312*f5c631daSSadaf Ebrahimi 
ShiftMoveWide(int64_t shift)7313*f5c631daSSadaf Ebrahimi   static Instr ShiftMoveWide(int64_t shift) {
7314*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint2(shift));
7315*f5c631daSSadaf Ebrahimi     return static_cast<Instr>(shift << ShiftMoveWide_offset);
7316*f5c631daSSadaf Ebrahimi   }
7317*f5c631daSSadaf Ebrahimi 
7318*f5c631daSSadaf Ebrahimi   // FP Immediates.
7319*f5c631daSSadaf Ebrahimi   static Instr ImmFP16(Float16 imm);
7320*f5c631daSSadaf Ebrahimi   static Instr ImmFP32(float imm);
7321*f5c631daSSadaf Ebrahimi   static Instr ImmFP64(double imm);
7322*f5c631daSSadaf Ebrahimi 
7323*f5c631daSSadaf Ebrahimi   // FP register type.
FPType(VRegister fd)7324*f5c631daSSadaf Ebrahimi   static Instr FPType(VRegister fd) {
7325*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(fd.IsScalar());
7326*f5c631daSSadaf Ebrahimi     switch (fd.GetSizeInBits()) {
7327*f5c631daSSadaf Ebrahimi       case 16:
7328*f5c631daSSadaf Ebrahimi         return FP16;
7329*f5c631daSSadaf Ebrahimi       case 32:
7330*f5c631daSSadaf Ebrahimi         return FP32;
7331*f5c631daSSadaf Ebrahimi       case 64:
7332*f5c631daSSadaf Ebrahimi         return FP64;
7333*f5c631daSSadaf Ebrahimi       default:
7334*f5c631daSSadaf Ebrahimi         VIXL_UNREACHABLE();
7335*f5c631daSSadaf Ebrahimi         return 0;
7336*f5c631daSSadaf Ebrahimi     }
7337*f5c631daSSadaf Ebrahimi   }
7338*f5c631daSSadaf Ebrahimi 
FPScale(unsigned scale)7339*f5c631daSSadaf Ebrahimi   static Instr FPScale(unsigned scale) {
7340*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint6(scale));
7341*f5c631daSSadaf Ebrahimi     return scale << FPScale_offset;
7342*f5c631daSSadaf Ebrahimi   }
7343*f5c631daSSadaf Ebrahimi 
7344*f5c631daSSadaf Ebrahimi   // Immediate field checking helpers.
7345*f5c631daSSadaf Ebrahimi   static bool IsImmAddSub(int64_t immediate);
7346*f5c631daSSadaf Ebrahimi   static bool IsImmConditionalCompare(int64_t immediate);
7347*f5c631daSSadaf Ebrahimi   static bool IsImmFP16(Float16 imm);
7348*f5c631daSSadaf Ebrahimi   static bool IsImmFP32(float imm);
7349*f5c631daSSadaf Ebrahimi   static bool IsImmFP64(double imm);
7350*f5c631daSSadaf Ebrahimi   static bool IsImmLogical(uint64_t value,
7351*f5c631daSSadaf Ebrahimi                            unsigned width,
7352*f5c631daSSadaf Ebrahimi                            unsigned* n = NULL,
7353*f5c631daSSadaf Ebrahimi                            unsigned* imm_s = NULL,
7354*f5c631daSSadaf Ebrahimi                            unsigned* imm_r = NULL);
7355*f5c631daSSadaf Ebrahimi   static bool IsImmLSPair(int64_t offset, unsigned access_size_in_bytes_log2);
7356*f5c631daSSadaf Ebrahimi   static bool IsImmLSScaled(int64_t offset, unsigned access_size_in_bytes_log2);
7357*f5c631daSSadaf Ebrahimi   static bool IsImmLSUnscaled(int64_t offset);
7358*f5c631daSSadaf Ebrahimi   static bool IsImmMovn(uint64_t imm, unsigned reg_size);
7359*f5c631daSSadaf Ebrahimi   static bool IsImmMovz(uint64_t imm, unsigned reg_size);
7360*f5c631daSSadaf Ebrahimi 
7361*f5c631daSSadaf Ebrahimi   // Instruction bits for vector format in data processing operations.
VFormat(VRegister vd)7362*f5c631daSSadaf Ebrahimi   static Instr VFormat(VRegister vd) {
7363*f5c631daSSadaf Ebrahimi     if (vd.Is64Bits()) {
7364*f5c631daSSadaf Ebrahimi       switch (vd.GetLanes()) {
7365*f5c631daSSadaf Ebrahimi         case 2:
7366*f5c631daSSadaf Ebrahimi           return NEON_2S;
7367*f5c631daSSadaf Ebrahimi         case 4:
7368*f5c631daSSadaf Ebrahimi           return NEON_4H;
7369*f5c631daSSadaf Ebrahimi         case 8:
7370*f5c631daSSadaf Ebrahimi           return NEON_8B;
7371*f5c631daSSadaf Ebrahimi         default:
7372*f5c631daSSadaf Ebrahimi           return 0xffffffff;
7373*f5c631daSSadaf Ebrahimi       }
7374*f5c631daSSadaf Ebrahimi     } else {
7375*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(vd.Is128Bits());
7376*f5c631daSSadaf Ebrahimi       switch (vd.GetLanes()) {
7377*f5c631daSSadaf Ebrahimi         case 2:
7378*f5c631daSSadaf Ebrahimi           return NEON_2D;
7379*f5c631daSSadaf Ebrahimi         case 4:
7380*f5c631daSSadaf Ebrahimi           return NEON_4S;
7381*f5c631daSSadaf Ebrahimi         case 8:
7382*f5c631daSSadaf Ebrahimi           return NEON_8H;
7383*f5c631daSSadaf Ebrahimi         case 16:
7384*f5c631daSSadaf Ebrahimi           return NEON_16B;
7385*f5c631daSSadaf Ebrahimi         default:
7386*f5c631daSSadaf Ebrahimi           return 0xffffffff;
7387*f5c631daSSadaf Ebrahimi       }
7388*f5c631daSSadaf Ebrahimi     }
7389*f5c631daSSadaf Ebrahimi   }
7390*f5c631daSSadaf Ebrahimi 
7391*f5c631daSSadaf Ebrahimi   // Instruction bits for vector format in floating point data processing
7392*f5c631daSSadaf Ebrahimi   // operations.
FPFormat(VRegister vd)7393*f5c631daSSadaf Ebrahimi   static Instr FPFormat(VRegister vd) {
7394*f5c631daSSadaf Ebrahimi     switch (vd.GetLanes()) {
7395*f5c631daSSadaf Ebrahimi       case 1:
7396*f5c631daSSadaf Ebrahimi         // Floating point scalar formats.
7397*f5c631daSSadaf Ebrahimi         switch (vd.GetSizeInBits()) {
7398*f5c631daSSadaf Ebrahimi           case 16:
7399*f5c631daSSadaf Ebrahimi             return FP16;
7400*f5c631daSSadaf Ebrahimi           case 32:
7401*f5c631daSSadaf Ebrahimi             return FP32;
7402*f5c631daSSadaf Ebrahimi           case 64:
7403*f5c631daSSadaf Ebrahimi             return FP64;
7404*f5c631daSSadaf Ebrahimi           default:
7405*f5c631daSSadaf Ebrahimi             VIXL_UNREACHABLE();
7406*f5c631daSSadaf Ebrahimi         }
7407*f5c631daSSadaf Ebrahimi         break;
7408*f5c631daSSadaf Ebrahimi       case 2:
7409*f5c631daSSadaf Ebrahimi         // Two lane floating point vector formats.
7410*f5c631daSSadaf Ebrahimi         switch (vd.GetSizeInBits()) {
7411*f5c631daSSadaf Ebrahimi           case 64:
7412*f5c631daSSadaf Ebrahimi             return NEON_FP_2S;
7413*f5c631daSSadaf Ebrahimi           case 128:
7414*f5c631daSSadaf Ebrahimi             return NEON_FP_2D;
7415*f5c631daSSadaf Ebrahimi           default:
7416*f5c631daSSadaf Ebrahimi             VIXL_UNREACHABLE();
7417*f5c631daSSadaf Ebrahimi         }
7418*f5c631daSSadaf Ebrahimi         break;
7419*f5c631daSSadaf Ebrahimi       case 4:
7420*f5c631daSSadaf Ebrahimi         // Four lane floating point vector formats.
7421*f5c631daSSadaf Ebrahimi         switch (vd.GetSizeInBits()) {
7422*f5c631daSSadaf Ebrahimi           case 64:
7423*f5c631daSSadaf Ebrahimi             return NEON_FP_4H;
7424*f5c631daSSadaf Ebrahimi           case 128:
7425*f5c631daSSadaf Ebrahimi             return NEON_FP_4S;
7426*f5c631daSSadaf Ebrahimi           default:
7427*f5c631daSSadaf Ebrahimi             VIXL_UNREACHABLE();
7428*f5c631daSSadaf Ebrahimi         }
7429*f5c631daSSadaf Ebrahimi         break;
7430*f5c631daSSadaf Ebrahimi       case 8:
7431*f5c631daSSadaf Ebrahimi         // Eight lane floating point vector format.
7432*f5c631daSSadaf Ebrahimi         VIXL_ASSERT(vd.Is128Bits());
7433*f5c631daSSadaf Ebrahimi         return NEON_FP_8H;
7434*f5c631daSSadaf Ebrahimi       default:
7435*f5c631daSSadaf Ebrahimi         VIXL_UNREACHABLE();
7436*f5c631daSSadaf Ebrahimi         return 0;
7437*f5c631daSSadaf Ebrahimi     }
7438*f5c631daSSadaf Ebrahimi     VIXL_UNREACHABLE();
7439*f5c631daSSadaf Ebrahimi     return 0;
7440*f5c631daSSadaf Ebrahimi   }
7441*f5c631daSSadaf Ebrahimi 
7442*f5c631daSSadaf Ebrahimi   // Instruction bits for vector format in load and store operations.
LSVFormat(VRegister vd)7443*f5c631daSSadaf Ebrahimi   static Instr LSVFormat(VRegister vd) {
7444*f5c631daSSadaf Ebrahimi     if (vd.Is64Bits()) {
7445*f5c631daSSadaf Ebrahimi       switch (vd.GetLanes()) {
7446*f5c631daSSadaf Ebrahimi         case 1:
7447*f5c631daSSadaf Ebrahimi           return LS_NEON_1D;
7448*f5c631daSSadaf Ebrahimi         case 2:
7449*f5c631daSSadaf Ebrahimi           return LS_NEON_2S;
7450*f5c631daSSadaf Ebrahimi         case 4:
7451*f5c631daSSadaf Ebrahimi           return LS_NEON_4H;
7452*f5c631daSSadaf Ebrahimi         case 8:
7453*f5c631daSSadaf Ebrahimi           return LS_NEON_8B;
7454*f5c631daSSadaf Ebrahimi         default:
7455*f5c631daSSadaf Ebrahimi           return 0xffffffff;
7456*f5c631daSSadaf Ebrahimi       }
7457*f5c631daSSadaf Ebrahimi     } else {
7458*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(vd.Is128Bits());
7459*f5c631daSSadaf Ebrahimi       switch (vd.GetLanes()) {
7460*f5c631daSSadaf Ebrahimi         case 2:
7461*f5c631daSSadaf Ebrahimi           return LS_NEON_2D;
7462*f5c631daSSadaf Ebrahimi         case 4:
7463*f5c631daSSadaf Ebrahimi           return LS_NEON_4S;
7464*f5c631daSSadaf Ebrahimi         case 8:
7465*f5c631daSSadaf Ebrahimi           return LS_NEON_8H;
7466*f5c631daSSadaf Ebrahimi         case 16:
7467*f5c631daSSadaf Ebrahimi           return LS_NEON_16B;
7468*f5c631daSSadaf Ebrahimi         default:
7469*f5c631daSSadaf Ebrahimi           return 0xffffffff;
7470*f5c631daSSadaf Ebrahimi       }
7471*f5c631daSSadaf Ebrahimi     }
7472*f5c631daSSadaf Ebrahimi   }
7473*f5c631daSSadaf Ebrahimi 
7474*f5c631daSSadaf Ebrahimi   // Instruction bits for scalar format in data processing operations.
SFormat(VRegister vd)7475*f5c631daSSadaf Ebrahimi   static Instr SFormat(VRegister vd) {
7476*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(vd.GetLanes() == 1);
7477*f5c631daSSadaf Ebrahimi     switch (vd.GetSizeInBytes()) {
7478*f5c631daSSadaf Ebrahimi       case 1:
7479*f5c631daSSadaf Ebrahimi         return NEON_B;
7480*f5c631daSSadaf Ebrahimi       case 2:
7481*f5c631daSSadaf Ebrahimi         return NEON_H;
7482*f5c631daSSadaf Ebrahimi       case 4:
7483*f5c631daSSadaf Ebrahimi         return NEON_S;
7484*f5c631daSSadaf Ebrahimi       case 8:
7485*f5c631daSSadaf Ebrahimi         return NEON_D;
7486*f5c631daSSadaf Ebrahimi       default:
7487*f5c631daSSadaf Ebrahimi         return 0xffffffff;
7488*f5c631daSSadaf Ebrahimi     }
7489*f5c631daSSadaf Ebrahimi   }
7490*f5c631daSSadaf Ebrahimi 
7491*f5c631daSSadaf Ebrahimi   template <typename T>
SVESize(const T & rd)7492*f5c631daSSadaf Ebrahimi   static Instr SVESize(const T& rd) {
7493*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(rd.IsZRegister() || rd.IsPRegister());
7494*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(rd.HasLaneSize());
7495*f5c631daSSadaf Ebrahimi     switch (rd.GetLaneSizeInBytes()) {
7496*f5c631daSSadaf Ebrahimi       case 1:
7497*f5c631daSSadaf Ebrahimi         return SVE_B;
7498*f5c631daSSadaf Ebrahimi       case 2:
7499*f5c631daSSadaf Ebrahimi         return SVE_H;
7500*f5c631daSSadaf Ebrahimi       case 4:
7501*f5c631daSSadaf Ebrahimi         return SVE_S;
7502*f5c631daSSadaf Ebrahimi       case 8:
7503*f5c631daSSadaf Ebrahimi         return SVE_D;
7504*f5c631daSSadaf Ebrahimi       default:
7505*f5c631daSSadaf Ebrahimi         return 0xffffffff;
7506*f5c631daSSadaf Ebrahimi     }
7507*f5c631daSSadaf Ebrahimi   }
7508*f5c631daSSadaf Ebrahimi 
ImmSVEPredicateConstraint(int pattern)7509*f5c631daSSadaf Ebrahimi   static Instr ImmSVEPredicateConstraint(int pattern) {
7510*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint5(pattern));
7511*f5c631daSSadaf Ebrahimi     return (pattern << ImmSVEPredicateConstraint_offset) &
7512*f5c631daSSadaf Ebrahimi            ImmSVEPredicateConstraint_mask;
7513*f5c631daSSadaf Ebrahimi   }
7514*f5c631daSSadaf Ebrahimi 
ImmNEONHLM(int index,int num_bits)7515*f5c631daSSadaf Ebrahimi   static Instr ImmNEONHLM(int index, int num_bits) {
7516*f5c631daSSadaf Ebrahimi     int h, l, m;
7517*f5c631daSSadaf Ebrahimi     if (num_bits == 3) {
7518*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(IsUint3(index));
7519*f5c631daSSadaf Ebrahimi       h = (index >> 2) & 1;
7520*f5c631daSSadaf Ebrahimi       l = (index >> 1) & 1;
7521*f5c631daSSadaf Ebrahimi       m = (index >> 0) & 1;
7522*f5c631daSSadaf Ebrahimi     } else if (num_bits == 2) {
7523*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(IsUint2(index));
7524*f5c631daSSadaf Ebrahimi       h = (index >> 1) & 1;
7525*f5c631daSSadaf Ebrahimi       l = (index >> 0) & 1;
7526*f5c631daSSadaf Ebrahimi       m = 0;
7527*f5c631daSSadaf Ebrahimi     } else {
7528*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(IsUint1(index) && (num_bits == 1));
7529*f5c631daSSadaf Ebrahimi       h = (index >> 0) & 1;
7530*f5c631daSSadaf Ebrahimi       l = 0;
7531*f5c631daSSadaf Ebrahimi       m = 0;
7532*f5c631daSSadaf Ebrahimi     }
7533*f5c631daSSadaf Ebrahimi     return (h << NEONH_offset) | (l << NEONL_offset) | (m << NEONM_offset);
7534*f5c631daSSadaf Ebrahimi   }
7535*f5c631daSSadaf Ebrahimi 
ImmRotFcadd(int rot)7536*f5c631daSSadaf Ebrahimi   static Instr ImmRotFcadd(int rot) {
7537*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(rot == 90 || rot == 270);
7538*f5c631daSSadaf Ebrahimi     return (((rot == 270) ? 1 : 0) << ImmRotFcadd_offset);
7539*f5c631daSSadaf Ebrahimi   }
7540*f5c631daSSadaf Ebrahimi 
ImmRotFcmlaSca(int rot)7541*f5c631daSSadaf Ebrahimi   static Instr ImmRotFcmlaSca(int rot) {
7542*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(rot == 0 || rot == 90 || rot == 180 || rot == 270);
7543*f5c631daSSadaf Ebrahimi     return (rot / 90) << ImmRotFcmlaSca_offset;
7544*f5c631daSSadaf Ebrahimi   }
7545*f5c631daSSadaf Ebrahimi 
ImmRotFcmlaVec(int rot)7546*f5c631daSSadaf Ebrahimi   static Instr ImmRotFcmlaVec(int rot) {
7547*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(rot == 0 || rot == 90 || rot == 180 || rot == 270);
7548*f5c631daSSadaf Ebrahimi     return (rot / 90) << ImmRotFcmlaVec_offset;
7549*f5c631daSSadaf Ebrahimi   }
7550*f5c631daSSadaf Ebrahimi 
ImmNEONExt(int imm4)7551*f5c631daSSadaf Ebrahimi   static Instr ImmNEONExt(int imm4) {
7552*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint4(imm4));
7553*f5c631daSSadaf Ebrahimi     return imm4 << ImmNEONExt_offset;
7554*f5c631daSSadaf Ebrahimi   }
7555*f5c631daSSadaf Ebrahimi 
ImmNEON5(Instr format,int index)7556*f5c631daSSadaf Ebrahimi   static Instr ImmNEON5(Instr format, int index) {
7557*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint4(index));
7558*f5c631daSSadaf Ebrahimi     int s = LaneSizeInBytesLog2FromFormat(static_cast<VectorFormat>(format));
7559*f5c631daSSadaf Ebrahimi     int imm5 = (index << (s + 1)) | (1 << s);
7560*f5c631daSSadaf Ebrahimi     return imm5 << ImmNEON5_offset;
7561*f5c631daSSadaf Ebrahimi   }
7562*f5c631daSSadaf Ebrahimi 
ImmNEON4(Instr format,int index)7563*f5c631daSSadaf Ebrahimi   static Instr ImmNEON4(Instr format, int index) {
7564*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint4(index));
7565*f5c631daSSadaf Ebrahimi     int s = LaneSizeInBytesLog2FromFormat(static_cast<VectorFormat>(format));
7566*f5c631daSSadaf Ebrahimi     int imm4 = index << s;
7567*f5c631daSSadaf Ebrahimi     return imm4 << ImmNEON4_offset;
7568*f5c631daSSadaf Ebrahimi   }
7569*f5c631daSSadaf Ebrahimi 
ImmNEONabcdefgh(int imm8)7570*f5c631daSSadaf Ebrahimi   static Instr ImmNEONabcdefgh(int imm8) {
7571*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint8(imm8));
7572*f5c631daSSadaf Ebrahimi     Instr instr;
7573*f5c631daSSadaf Ebrahimi     instr = ((imm8 >> 5) & 7) << ImmNEONabc_offset;
7574*f5c631daSSadaf Ebrahimi     instr |= (imm8 & 0x1f) << ImmNEONdefgh_offset;
7575*f5c631daSSadaf Ebrahimi     return instr;
7576*f5c631daSSadaf Ebrahimi   }
7577*f5c631daSSadaf Ebrahimi 
NEONCmode(int cmode)7578*f5c631daSSadaf Ebrahimi   static Instr NEONCmode(int cmode) {
7579*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint4(cmode));
7580*f5c631daSSadaf Ebrahimi     return cmode << NEONCmode_offset;
7581*f5c631daSSadaf Ebrahimi   }
7582*f5c631daSSadaf Ebrahimi 
NEONModImmOp(int op)7583*f5c631daSSadaf Ebrahimi   static Instr NEONModImmOp(int op) {
7584*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsUint1(op));
7585*f5c631daSSadaf Ebrahimi     return op << NEONModImmOp_offset;
7586*f5c631daSSadaf Ebrahimi   }
7587*f5c631daSSadaf Ebrahimi 
7588*f5c631daSSadaf Ebrahimi   // Size of the code generated since label to the current position.
GetSizeOfCodeGeneratedSince(Label * label)7589*f5c631daSSadaf Ebrahimi   size_t GetSizeOfCodeGeneratedSince(Label* label) const {
7590*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(label->IsBound());
7591*f5c631daSSadaf Ebrahimi     return GetBuffer().GetOffsetFrom(label->GetLocation());
7592*f5c631daSSadaf Ebrahimi   }
7593*f5c631daSSadaf Ebrahimi   VIXL_DEPRECATED("GetSizeOfCodeGeneratedSince",
7594*f5c631daSSadaf Ebrahimi                   size_t SizeOfCodeGeneratedSince(Label* label) const) {
7595*f5c631daSSadaf Ebrahimi     return GetSizeOfCodeGeneratedSince(label);
7596*f5c631daSSadaf Ebrahimi   }
7597*f5c631daSSadaf Ebrahimi 
7598*f5c631daSSadaf Ebrahimi   VIXL_DEPRECATED("GetBuffer().GetCapacity()",
7599*f5c631daSSadaf Ebrahimi                   size_t GetBufferCapacity() const) {
7600*f5c631daSSadaf Ebrahimi     return GetBuffer().GetCapacity();
7601*f5c631daSSadaf Ebrahimi   }
7602*f5c631daSSadaf Ebrahimi   VIXL_DEPRECATED("GetBuffer().GetCapacity()", size_t BufferCapacity() const) {
7603*f5c631daSSadaf Ebrahimi     return GetBuffer().GetCapacity();
7604*f5c631daSSadaf Ebrahimi   }
7605*f5c631daSSadaf Ebrahimi 
7606*f5c631daSSadaf Ebrahimi   VIXL_DEPRECATED("GetBuffer().GetRemainingBytes()",
7607*f5c631daSSadaf Ebrahimi                   size_t GetRemainingBufferSpace() const) {
7608*f5c631daSSadaf Ebrahimi     return GetBuffer().GetRemainingBytes();
7609*f5c631daSSadaf Ebrahimi   }
7610*f5c631daSSadaf Ebrahimi   VIXL_DEPRECATED("GetBuffer().GetRemainingBytes()",
7611*f5c631daSSadaf Ebrahimi                   size_t RemainingBufferSpace() const) {
7612*f5c631daSSadaf Ebrahimi     return GetBuffer().GetRemainingBytes();
7613*f5c631daSSadaf Ebrahimi   }
7614*f5c631daSSadaf Ebrahimi 
GetPic()7615*f5c631daSSadaf Ebrahimi   PositionIndependentCodeOption GetPic() const { return pic_; }
7616*f5c631daSSadaf Ebrahimi   VIXL_DEPRECATED("GetPic", PositionIndependentCodeOption pic() const) {
7617*f5c631daSSadaf Ebrahimi     return GetPic();
7618*f5c631daSSadaf Ebrahimi   }
7619*f5c631daSSadaf Ebrahimi 
GetCPUFeatures()7620*f5c631daSSadaf Ebrahimi   CPUFeatures* GetCPUFeatures() { return &cpu_features_; }
7621*f5c631daSSadaf Ebrahimi 
SetCPUFeatures(const CPUFeatures & cpu_features)7622*f5c631daSSadaf Ebrahimi   void SetCPUFeatures(const CPUFeatures& cpu_features) {
7623*f5c631daSSadaf Ebrahimi     cpu_features_ = cpu_features;
7624*f5c631daSSadaf Ebrahimi   }
7625*f5c631daSSadaf Ebrahimi 
AllowPageOffsetDependentCode()7626*f5c631daSSadaf Ebrahimi   bool AllowPageOffsetDependentCode() const {
7627*f5c631daSSadaf Ebrahimi     return (GetPic() == PageOffsetDependentCode) ||
7628*f5c631daSSadaf Ebrahimi            (GetPic() == PositionDependentCode);
7629*f5c631daSSadaf Ebrahimi   }
7630*f5c631daSSadaf Ebrahimi 
AppropriateZeroRegFor(const CPURegister & reg)7631*f5c631daSSadaf Ebrahimi   static Register AppropriateZeroRegFor(const CPURegister& reg) {
7632*f5c631daSSadaf Ebrahimi     return reg.Is64Bits() ? Register(xzr) : Register(wzr);
7633*f5c631daSSadaf Ebrahimi   }
7634*f5c631daSSadaf Ebrahimi 
7635*f5c631daSSadaf Ebrahimi  protected:
7636*f5c631daSSadaf Ebrahimi   void LoadStore(const CPURegister& rt,
7637*f5c631daSSadaf Ebrahimi                  const MemOperand& addr,
7638*f5c631daSSadaf Ebrahimi                  LoadStoreOp op,
7639*f5c631daSSadaf Ebrahimi                  LoadStoreScalingOption option = PreferScaledOffset);
7640*f5c631daSSadaf Ebrahimi 
7641*f5c631daSSadaf Ebrahimi   void LoadStorePAC(const Register& xt,
7642*f5c631daSSadaf Ebrahimi                     const MemOperand& addr,
7643*f5c631daSSadaf Ebrahimi                     LoadStorePACOp op);
7644*f5c631daSSadaf Ebrahimi 
7645*f5c631daSSadaf Ebrahimi   void LoadStorePair(const CPURegister& rt,
7646*f5c631daSSadaf Ebrahimi                      const CPURegister& rt2,
7647*f5c631daSSadaf Ebrahimi                      const MemOperand& addr,
7648*f5c631daSSadaf Ebrahimi                      LoadStorePairOp op);
7649*f5c631daSSadaf Ebrahimi   void LoadStoreStruct(const VRegister& vt,
7650*f5c631daSSadaf Ebrahimi                        const MemOperand& addr,
7651*f5c631daSSadaf Ebrahimi                        NEONLoadStoreMultiStructOp op);
7652*f5c631daSSadaf Ebrahimi   void LoadStoreStruct1(const VRegister& vt,
7653*f5c631daSSadaf Ebrahimi                         int reg_count,
7654*f5c631daSSadaf Ebrahimi                         const MemOperand& addr);
7655*f5c631daSSadaf Ebrahimi   void LoadStoreStructSingle(const VRegister& vt,
7656*f5c631daSSadaf Ebrahimi                              uint32_t lane,
7657*f5c631daSSadaf Ebrahimi                              const MemOperand& addr,
7658*f5c631daSSadaf Ebrahimi                              NEONLoadStoreSingleStructOp op);
7659*f5c631daSSadaf Ebrahimi   void LoadStoreStructSingleAllLanes(const VRegister& vt,
7660*f5c631daSSadaf Ebrahimi                                      const MemOperand& addr,
7661*f5c631daSSadaf Ebrahimi                                      NEONLoadStoreSingleStructOp op);
7662*f5c631daSSadaf Ebrahimi   void LoadStoreStructVerify(const VRegister& vt,
7663*f5c631daSSadaf Ebrahimi                              const MemOperand& addr,
7664*f5c631daSSadaf Ebrahimi                              Instr op);
7665*f5c631daSSadaf Ebrahimi 
7666*f5c631daSSadaf Ebrahimi   // Set `is_load` to false in default as it's only used in the
7667*f5c631daSSadaf Ebrahimi   // scalar-plus-vector form.
7668*f5c631daSSadaf Ebrahimi   Instr SVEMemOperandHelper(unsigned msize_in_bytes_log2,
7669*f5c631daSSadaf Ebrahimi                             int num_regs,
7670*f5c631daSSadaf Ebrahimi                             const SVEMemOperand& addr,
7671*f5c631daSSadaf Ebrahimi                             bool is_load = false);
7672*f5c631daSSadaf Ebrahimi 
7673*f5c631daSSadaf Ebrahimi   // E.g. st1b, st1h, ...
7674*f5c631daSSadaf Ebrahimi   // This supports both contiguous and scatter stores.
7675*f5c631daSSadaf Ebrahimi   void SVESt1Helper(unsigned msize_in_bytes_log2,
7676*f5c631daSSadaf Ebrahimi                     const ZRegister& zt,
7677*f5c631daSSadaf Ebrahimi                     const PRegister& pg,
7678*f5c631daSSadaf Ebrahimi                     const SVEMemOperand& addr);
7679*f5c631daSSadaf Ebrahimi 
7680*f5c631daSSadaf Ebrahimi   // E.g. ld1b, ld1h, ...
7681*f5c631daSSadaf Ebrahimi   // This supports both contiguous and gather loads.
7682*f5c631daSSadaf Ebrahimi   void SVELd1Helper(unsigned msize_in_bytes_log2,
7683*f5c631daSSadaf Ebrahimi                     const ZRegister& zt,
7684*f5c631daSSadaf Ebrahimi                     const PRegisterZ& pg,
7685*f5c631daSSadaf Ebrahimi                     const SVEMemOperand& addr,
7686*f5c631daSSadaf Ebrahimi                     bool is_signed);
7687*f5c631daSSadaf Ebrahimi 
7688*f5c631daSSadaf Ebrahimi   // E.g. ld1rb, ld1rh, ...
7689*f5c631daSSadaf Ebrahimi   void SVELd1BroadcastHelper(unsigned msize_in_bytes_log2,
7690*f5c631daSSadaf Ebrahimi                              const ZRegister& zt,
7691*f5c631daSSadaf Ebrahimi                              const PRegisterZ& pg,
7692*f5c631daSSadaf Ebrahimi                              const SVEMemOperand& addr,
7693*f5c631daSSadaf Ebrahimi                              bool is_signed);
7694*f5c631daSSadaf Ebrahimi 
7695*f5c631daSSadaf Ebrahimi   // E.g. ldff1b, ldff1h, ...
7696*f5c631daSSadaf Ebrahimi   // This supports both contiguous and gather loads.
7697*f5c631daSSadaf Ebrahimi   void SVELdff1Helper(unsigned msize_in_bytes_log2,
7698*f5c631daSSadaf Ebrahimi                       const ZRegister& zt,
7699*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
7700*f5c631daSSadaf Ebrahimi                       const SVEMemOperand& addr,
7701*f5c631daSSadaf Ebrahimi                       bool is_signed);
7702*f5c631daSSadaf Ebrahimi 
7703*f5c631daSSadaf Ebrahimi   // Common code for the helpers above.
7704*f5c631daSSadaf Ebrahimi   void SVELdSt1Helper(unsigned msize_in_bytes_log2,
7705*f5c631daSSadaf Ebrahimi                       const ZRegister& zt,
7706*f5c631daSSadaf Ebrahimi                       const PRegister& pg,
7707*f5c631daSSadaf Ebrahimi                       const SVEMemOperand& addr,
7708*f5c631daSSadaf Ebrahimi                       bool is_signed,
7709*f5c631daSSadaf Ebrahimi                       Instr op);
7710*f5c631daSSadaf Ebrahimi 
7711*f5c631daSSadaf Ebrahimi   // Common code for the helpers above.
7712*f5c631daSSadaf Ebrahimi   void SVEScatterGatherHelper(unsigned msize_in_bytes_log2,
7713*f5c631daSSadaf Ebrahimi                               const ZRegister& zt,
7714*f5c631daSSadaf Ebrahimi                               const PRegister& pg,
7715*f5c631daSSadaf Ebrahimi                               const SVEMemOperand& addr,
7716*f5c631daSSadaf Ebrahimi                               bool is_load,
7717*f5c631daSSadaf Ebrahimi                               bool is_signed,
7718*f5c631daSSadaf Ebrahimi                               bool is_first_fault);
7719*f5c631daSSadaf Ebrahimi 
7720*f5c631daSSadaf Ebrahimi   // E.g. st2b, st3h, ...
7721*f5c631daSSadaf Ebrahimi   void SVESt234Helper(int num_regs,
7722*f5c631daSSadaf Ebrahimi                       const ZRegister& zt1,
7723*f5c631daSSadaf Ebrahimi                       const PRegister& pg,
7724*f5c631daSSadaf Ebrahimi                       const SVEMemOperand& addr);
7725*f5c631daSSadaf Ebrahimi 
7726*f5c631daSSadaf Ebrahimi   // E.g. ld2b, ld3h, ...
7727*f5c631daSSadaf Ebrahimi   void SVELd234Helper(int num_regs,
7728*f5c631daSSadaf Ebrahimi                       const ZRegister& zt1,
7729*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
7730*f5c631daSSadaf Ebrahimi                       const SVEMemOperand& addr);
7731*f5c631daSSadaf Ebrahimi 
7732*f5c631daSSadaf Ebrahimi   // Common code for the helpers above.
7733*f5c631daSSadaf Ebrahimi   void SVELdSt234Helper(int num_regs,
7734*f5c631daSSadaf Ebrahimi                         const ZRegister& zt1,
7735*f5c631daSSadaf Ebrahimi                         const PRegister& pg,
7736*f5c631daSSadaf Ebrahimi                         const SVEMemOperand& addr,
7737*f5c631daSSadaf Ebrahimi                         Instr op);
7738*f5c631daSSadaf Ebrahimi 
7739*f5c631daSSadaf Ebrahimi   // E.g. ld1qb, ld1qh, ldnt1b, ...
7740*f5c631daSSadaf Ebrahimi   void SVELd1St1ScaImmHelper(const ZRegister& zt,
7741*f5c631daSSadaf Ebrahimi                              const PRegister& pg,
7742*f5c631daSSadaf Ebrahimi                              const SVEMemOperand& addr,
7743*f5c631daSSadaf Ebrahimi                              Instr regoffset_op,
7744*f5c631daSSadaf Ebrahimi                              Instr immoffset_op,
7745*f5c631daSSadaf Ebrahimi                              int imm_divisor = 1);
7746*f5c631daSSadaf Ebrahimi 
7747*f5c631daSSadaf Ebrahimi   void SVELd1VecScaHelper(const ZRegister& zt,
7748*f5c631daSSadaf Ebrahimi                           const PRegister& pg,
7749*f5c631daSSadaf Ebrahimi                           const SVEMemOperand& addr,
7750*f5c631daSSadaf Ebrahimi                           uint32_t msize,
7751*f5c631daSSadaf Ebrahimi                           bool is_signed);
7752*f5c631daSSadaf Ebrahimi   void SVESt1VecScaHelper(const ZRegister& zt,
7753*f5c631daSSadaf Ebrahimi                           const PRegister& pg,
7754*f5c631daSSadaf Ebrahimi                           const SVEMemOperand& addr,
7755*f5c631daSSadaf Ebrahimi                           uint32_t msize);
7756*f5c631daSSadaf Ebrahimi 
7757*f5c631daSSadaf Ebrahimi   void Prefetch(PrefetchOperation op,
7758*f5c631daSSadaf Ebrahimi                 const MemOperand& addr,
7759*f5c631daSSadaf Ebrahimi                 LoadStoreScalingOption option = PreferScaledOffset);
7760*f5c631daSSadaf Ebrahimi   void Prefetch(int op,
7761*f5c631daSSadaf Ebrahimi                 const MemOperand& addr,
7762*f5c631daSSadaf Ebrahimi                 LoadStoreScalingOption option = PreferScaledOffset);
7763*f5c631daSSadaf Ebrahimi 
7764*f5c631daSSadaf Ebrahimi   // TODO(all): The third parameter should be passed by reference but gcc 4.8.2
7765*f5c631daSSadaf Ebrahimi   // reports a bogus uninitialised warning then.
7766*f5c631daSSadaf Ebrahimi   void Logical(const Register& rd,
7767*f5c631daSSadaf Ebrahimi                const Register& rn,
7768*f5c631daSSadaf Ebrahimi                const Operand operand,
7769*f5c631daSSadaf Ebrahimi                LogicalOp op);
7770*f5c631daSSadaf Ebrahimi 
7771*f5c631daSSadaf Ebrahimi   void SVELogicalImmediate(const ZRegister& zd, uint64_t imm, Instr op);
7772*f5c631daSSadaf Ebrahimi 
7773*f5c631daSSadaf Ebrahimi   void LogicalImmediate(const Register& rd,
7774*f5c631daSSadaf Ebrahimi                         const Register& rn,
7775*f5c631daSSadaf Ebrahimi                         unsigned n,
7776*f5c631daSSadaf Ebrahimi                         unsigned imm_s,
7777*f5c631daSSadaf Ebrahimi                         unsigned imm_r,
7778*f5c631daSSadaf Ebrahimi                         LogicalOp op);
7779*f5c631daSSadaf Ebrahimi 
7780*f5c631daSSadaf Ebrahimi   void ConditionalCompare(const Register& rn,
7781*f5c631daSSadaf Ebrahimi                           const Operand& operand,
7782*f5c631daSSadaf Ebrahimi                           StatusFlags nzcv,
7783*f5c631daSSadaf Ebrahimi                           Condition cond,
7784*f5c631daSSadaf Ebrahimi                           ConditionalCompareOp op);
7785*f5c631daSSadaf Ebrahimi 
7786*f5c631daSSadaf Ebrahimi   void AddSubWithCarry(const Register& rd,
7787*f5c631daSSadaf Ebrahimi                        const Register& rn,
7788*f5c631daSSadaf Ebrahimi                        const Operand& operand,
7789*f5c631daSSadaf Ebrahimi                        FlagsUpdate S,
7790*f5c631daSSadaf Ebrahimi                        AddSubWithCarryOp op);
7791*f5c631daSSadaf Ebrahimi 
7792*f5c631daSSadaf Ebrahimi   void CompareVectors(const PRegisterWithLaneSize& pd,
7793*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
7794*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
7795*f5c631daSSadaf Ebrahimi                       const ZRegister& zm,
7796*f5c631daSSadaf Ebrahimi                       SVEIntCompareVectorsOp op);
7797*f5c631daSSadaf Ebrahimi 
7798*f5c631daSSadaf Ebrahimi   void CompareVectors(const PRegisterWithLaneSize& pd,
7799*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
7800*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
7801*f5c631daSSadaf Ebrahimi                       int imm,
7802*f5c631daSSadaf Ebrahimi                       SVEIntCompareSignedImmOp op);
7803*f5c631daSSadaf Ebrahimi 
7804*f5c631daSSadaf Ebrahimi   void CompareVectors(const PRegisterWithLaneSize& pd,
7805*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
7806*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
7807*f5c631daSSadaf Ebrahimi                       unsigned imm,
7808*f5c631daSSadaf Ebrahimi                       SVEIntCompareUnsignedImmOp op);
7809*f5c631daSSadaf Ebrahimi 
7810*f5c631daSSadaf Ebrahimi   void SVEIntAddSubtractImmUnpredicatedHelper(
7811*f5c631daSSadaf Ebrahimi       SVEIntAddSubtractImm_UnpredicatedOp op,
7812*f5c631daSSadaf Ebrahimi       const ZRegister& zd,
7813*f5c631daSSadaf Ebrahimi       int imm8,
7814*f5c631daSSadaf Ebrahimi       int shift);
7815*f5c631daSSadaf Ebrahimi 
7816*f5c631daSSadaf Ebrahimi   void SVEElementCountToRegisterHelper(Instr op,
7817*f5c631daSSadaf Ebrahimi                                        const Register& rd,
7818*f5c631daSSadaf Ebrahimi                                        int pattern,
7819*f5c631daSSadaf Ebrahimi                                        int multiplier);
7820*f5c631daSSadaf Ebrahimi 
7821*f5c631daSSadaf Ebrahimi   Instr EncodeSVEShiftLeftImmediate(int shift, int lane_size_in_bits);
7822*f5c631daSSadaf Ebrahimi 
7823*f5c631daSSadaf Ebrahimi   Instr EncodeSVEShiftRightImmediate(int shift, int lane_size_in_bits);
7824*f5c631daSSadaf Ebrahimi 
7825*f5c631daSSadaf Ebrahimi   void SVEBitwiseShiftImmediate(const ZRegister& zd,
7826*f5c631daSSadaf Ebrahimi                                 const ZRegister& zn,
7827*f5c631daSSadaf Ebrahimi                                 Instr encoded_imm,
7828*f5c631daSSadaf Ebrahimi                                 Instr op);
7829*f5c631daSSadaf Ebrahimi 
7830*f5c631daSSadaf Ebrahimi   void SVEBitwiseShiftImmediatePred(const ZRegister& zdn,
7831*f5c631daSSadaf Ebrahimi                                     const PRegisterM& pg,
7832*f5c631daSSadaf Ebrahimi                                     Instr encoded_imm,
7833*f5c631daSSadaf Ebrahimi                                     Instr op);
7834*f5c631daSSadaf Ebrahimi 
7835*f5c631daSSadaf Ebrahimi   Instr SVEMulIndexHelper(unsigned lane_size_in_bytes_log2,
7836*f5c631daSSadaf Ebrahimi                           const ZRegister& zm,
7837*f5c631daSSadaf Ebrahimi                           int index,
7838*f5c631daSSadaf Ebrahimi                           Instr op_h,
7839*f5c631daSSadaf Ebrahimi                           Instr op_s,
7840*f5c631daSSadaf Ebrahimi                           Instr op_d);
7841*f5c631daSSadaf Ebrahimi 
7842*f5c631daSSadaf Ebrahimi   Instr SVEMulLongIndexHelper(const ZRegister& zm, int index);
7843*f5c631daSSadaf Ebrahimi 
7844*f5c631daSSadaf Ebrahimi   Instr SVEMulComplexIndexHelper(const ZRegister& zm, int index);
7845*f5c631daSSadaf Ebrahimi 
7846*f5c631daSSadaf Ebrahimi   void SVEContiguousPrefetchScalarPlusScalarHelper(PrefetchOperation prfop,
7847*f5c631daSSadaf Ebrahimi                                                    const PRegister& pg,
7848*f5c631daSSadaf Ebrahimi                                                    const SVEMemOperand& addr,
7849*f5c631daSSadaf Ebrahimi                                                    int prefetch_size);
7850*f5c631daSSadaf Ebrahimi 
7851*f5c631daSSadaf Ebrahimi   void SVEContiguousPrefetchScalarPlusVectorHelper(PrefetchOperation prfop,
7852*f5c631daSSadaf Ebrahimi                                                    const PRegister& pg,
7853*f5c631daSSadaf Ebrahimi                                                    const SVEMemOperand& addr,
7854*f5c631daSSadaf Ebrahimi                                                    int prefetch_size);
7855*f5c631daSSadaf Ebrahimi 
7856*f5c631daSSadaf Ebrahimi   void SVEGatherPrefetchVectorPlusImmediateHelper(PrefetchOperation prfop,
7857*f5c631daSSadaf Ebrahimi                                                   const PRegister& pg,
7858*f5c631daSSadaf Ebrahimi                                                   const SVEMemOperand& addr,
7859*f5c631daSSadaf Ebrahimi                                                   int prefetch_size);
7860*f5c631daSSadaf Ebrahimi 
7861*f5c631daSSadaf Ebrahimi   void SVEGatherPrefetchScalarPlusImmediateHelper(PrefetchOperation prfop,
7862*f5c631daSSadaf Ebrahimi                                                   const PRegister& pg,
7863*f5c631daSSadaf Ebrahimi                                                   const SVEMemOperand& addr,
7864*f5c631daSSadaf Ebrahimi                                                   int prefetch_size);
7865*f5c631daSSadaf Ebrahimi 
7866*f5c631daSSadaf Ebrahimi   void SVEPrefetchHelper(PrefetchOperation prfop,
7867*f5c631daSSadaf Ebrahimi                          const PRegister& pg,
7868*f5c631daSSadaf Ebrahimi                          const SVEMemOperand& addr,
7869*f5c631daSSadaf Ebrahimi                          int prefetch_size);
7870*f5c631daSSadaf Ebrahimi 
SVEImmPrefetchOperation(PrefetchOperation prfop)7871*f5c631daSSadaf Ebrahimi   static Instr SVEImmPrefetchOperation(PrefetchOperation prfop) {
7872*f5c631daSSadaf Ebrahimi     // SVE only supports PLD and PST, not PLI.
7873*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(((prfop >= PLDL1KEEP) && (prfop <= PLDL3STRM)) ||
7874*f5c631daSSadaf Ebrahimi                 ((prfop >= PSTL1KEEP) && (prfop <= PSTL3STRM)));
7875*f5c631daSSadaf Ebrahimi     // Check that we can simply map bits.
7876*f5c631daSSadaf Ebrahimi     VIXL_STATIC_ASSERT(PLDL1KEEP == 0b00000);
7877*f5c631daSSadaf Ebrahimi     VIXL_STATIC_ASSERT(PSTL1KEEP == 0b10000);
7878*f5c631daSSadaf Ebrahimi     // Remaining operations map directly.
7879*f5c631daSSadaf Ebrahimi     return ((prfop & 0b10000) >> 1) | (prfop & 0b00111);
7880*f5c631daSSadaf Ebrahimi   }
7881*f5c631daSSadaf Ebrahimi 
7882*f5c631daSSadaf Ebrahimi   // Functions for emulating operands not directly supported by the instruction
7883*f5c631daSSadaf Ebrahimi   // set.
7884*f5c631daSSadaf Ebrahimi   void EmitShift(const Register& rd,
7885*f5c631daSSadaf Ebrahimi                  const Register& rn,
7886*f5c631daSSadaf Ebrahimi                  Shift shift,
7887*f5c631daSSadaf Ebrahimi                  unsigned amount);
7888*f5c631daSSadaf Ebrahimi   void EmitExtendShift(const Register& rd,
7889*f5c631daSSadaf Ebrahimi                        const Register& rn,
7890*f5c631daSSadaf Ebrahimi                        Extend extend,
7891*f5c631daSSadaf Ebrahimi                        unsigned left_shift);
7892*f5c631daSSadaf Ebrahimi 
7893*f5c631daSSadaf Ebrahimi   void AddSub(const Register& rd,
7894*f5c631daSSadaf Ebrahimi               const Register& rn,
7895*f5c631daSSadaf Ebrahimi               const Operand& operand,
7896*f5c631daSSadaf Ebrahimi               FlagsUpdate S,
7897*f5c631daSSadaf Ebrahimi               AddSubOp op);
7898*f5c631daSSadaf Ebrahimi 
7899*f5c631daSSadaf Ebrahimi   void NEONTable(const VRegister& vd,
7900*f5c631daSSadaf Ebrahimi                  const VRegister& vn,
7901*f5c631daSSadaf Ebrahimi                  const VRegister& vm,
7902*f5c631daSSadaf Ebrahimi                  NEONTableOp op);
7903*f5c631daSSadaf Ebrahimi 
7904*f5c631daSSadaf Ebrahimi   // Find an appropriate LoadStoreOp or LoadStorePairOp for the specified
7905*f5c631daSSadaf Ebrahimi   // registers. Only simple loads are supported; sign- and zero-extension (such
7906*f5c631daSSadaf Ebrahimi   // as in LDPSW_x or LDRB_w) are not supported.
7907*f5c631daSSadaf Ebrahimi   static LoadStoreOp LoadOpFor(const CPURegister& rt);
7908*f5c631daSSadaf Ebrahimi   static LoadStorePairOp LoadPairOpFor(const CPURegister& rt,
7909*f5c631daSSadaf Ebrahimi                                        const CPURegister& rt2);
7910*f5c631daSSadaf Ebrahimi   static LoadStoreOp StoreOpFor(const CPURegister& rt);
7911*f5c631daSSadaf Ebrahimi   static LoadStorePairOp StorePairOpFor(const CPURegister& rt,
7912*f5c631daSSadaf Ebrahimi                                         const CPURegister& rt2);
7913*f5c631daSSadaf Ebrahimi   static LoadStorePairNonTemporalOp LoadPairNonTemporalOpFor(
7914*f5c631daSSadaf Ebrahimi       const CPURegister& rt, const CPURegister& rt2);
7915*f5c631daSSadaf Ebrahimi   static LoadStorePairNonTemporalOp StorePairNonTemporalOpFor(
7916*f5c631daSSadaf Ebrahimi       const CPURegister& rt, const CPURegister& rt2);
7917*f5c631daSSadaf Ebrahimi   static LoadLiteralOp LoadLiteralOpFor(const CPURegister& rt);
7918*f5c631daSSadaf Ebrahimi 
7919*f5c631daSSadaf Ebrahimi   // Convenience pass-through for CPU feature checks.
7920*f5c631daSSadaf Ebrahimi   bool CPUHas(CPUFeatures::Feature feature0,
7921*f5c631daSSadaf Ebrahimi               CPUFeatures::Feature feature1 = CPUFeatures::kNone,
7922*f5c631daSSadaf Ebrahimi               CPUFeatures::Feature feature2 = CPUFeatures::kNone,
7923*f5c631daSSadaf Ebrahimi               CPUFeatures::Feature feature3 = CPUFeatures::kNone) const {
7924*f5c631daSSadaf Ebrahimi     return cpu_features_.Has(feature0, feature1, feature2, feature3);
7925*f5c631daSSadaf Ebrahimi   }
7926*f5c631daSSadaf Ebrahimi 
7927*f5c631daSSadaf Ebrahimi   // Determine whether the target CPU has the specified registers, based on the
7928*f5c631daSSadaf Ebrahimi   // currently-enabled CPU features. Presence of a register does not imply
7929*f5c631daSSadaf Ebrahimi   // support for arbitrary operations on it. For example, CPUs with FP have H
7930*f5c631daSSadaf Ebrahimi   // registers, but most half-precision operations require the FPHalf feature.
7931*f5c631daSSadaf Ebrahimi   //
7932*f5c631daSSadaf Ebrahimi   // These are used to check CPU features in loads and stores that have the same
7933*f5c631daSSadaf Ebrahimi   // entry point for both integer and FP registers.
7934*f5c631daSSadaf Ebrahimi   bool CPUHas(const CPURegister& rt) const;
7935*f5c631daSSadaf Ebrahimi   bool CPUHas(const CPURegister& rt, const CPURegister& rt2) const;
7936*f5c631daSSadaf Ebrahimi 
7937*f5c631daSSadaf Ebrahimi   bool CPUHas(SystemRegister sysreg) const;
7938*f5c631daSSadaf Ebrahimi 
7939*f5c631daSSadaf Ebrahimi  private:
7940*f5c631daSSadaf Ebrahimi   static uint32_t FP16ToImm8(Float16 imm);
7941*f5c631daSSadaf Ebrahimi   static uint32_t FP32ToImm8(float imm);
7942*f5c631daSSadaf Ebrahimi   static uint32_t FP64ToImm8(double imm);
7943*f5c631daSSadaf Ebrahimi 
7944*f5c631daSSadaf Ebrahimi   // Instruction helpers.
7945*f5c631daSSadaf Ebrahimi   void MoveWide(const Register& rd,
7946*f5c631daSSadaf Ebrahimi                 uint64_t imm,
7947*f5c631daSSadaf Ebrahimi                 int shift,
7948*f5c631daSSadaf Ebrahimi                 MoveWideImmediateOp mov_op);
7949*f5c631daSSadaf Ebrahimi   void DataProcShiftedRegister(const Register& rd,
7950*f5c631daSSadaf Ebrahimi                                const Register& rn,
7951*f5c631daSSadaf Ebrahimi                                const Operand& operand,
7952*f5c631daSSadaf Ebrahimi                                FlagsUpdate S,
7953*f5c631daSSadaf Ebrahimi                                Instr op);
7954*f5c631daSSadaf Ebrahimi   void DataProcExtendedRegister(const Register& rd,
7955*f5c631daSSadaf Ebrahimi                                 const Register& rn,
7956*f5c631daSSadaf Ebrahimi                                 const Operand& operand,
7957*f5c631daSSadaf Ebrahimi                                 FlagsUpdate S,
7958*f5c631daSSadaf Ebrahimi                                 Instr op);
7959*f5c631daSSadaf Ebrahimi   void LoadStorePairNonTemporal(const CPURegister& rt,
7960*f5c631daSSadaf Ebrahimi                                 const CPURegister& rt2,
7961*f5c631daSSadaf Ebrahimi                                 const MemOperand& addr,
7962*f5c631daSSadaf Ebrahimi                                 LoadStorePairNonTemporalOp op);
7963*f5c631daSSadaf Ebrahimi   void LoadLiteral(const CPURegister& rt, uint64_t imm, LoadLiteralOp op);
7964*f5c631daSSadaf Ebrahimi   void ConditionalSelect(const Register& rd,
7965*f5c631daSSadaf Ebrahimi                          const Register& rn,
7966*f5c631daSSadaf Ebrahimi                          const Register& rm,
7967*f5c631daSSadaf Ebrahimi                          Condition cond,
7968*f5c631daSSadaf Ebrahimi                          ConditionalSelectOp op);
7969*f5c631daSSadaf Ebrahimi   void DataProcessing1Source(const Register& rd,
7970*f5c631daSSadaf Ebrahimi                              const Register& rn,
7971*f5c631daSSadaf Ebrahimi                              DataProcessing1SourceOp op);
7972*f5c631daSSadaf Ebrahimi   void DataProcessing3Source(const Register& rd,
7973*f5c631daSSadaf Ebrahimi                              const Register& rn,
7974*f5c631daSSadaf Ebrahimi                              const Register& rm,
7975*f5c631daSSadaf Ebrahimi                              const Register& ra,
7976*f5c631daSSadaf Ebrahimi                              DataProcessing3SourceOp op);
7977*f5c631daSSadaf Ebrahimi   void FPDataProcessing1Source(const VRegister& fd,
7978*f5c631daSSadaf Ebrahimi                                const VRegister& fn,
7979*f5c631daSSadaf Ebrahimi                                FPDataProcessing1SourceOp op);
7980*f5c631daSSadaf Ebrahimi   void FPDataProcessing3Source(const VRegister& fd,
7981*f5c631daSSadaf Ebrahimi                                const VRegister& fn,
7982*f5c631daSSadaf Ebrahimi                                const VRegister& fm,
7983*f5c631daSSadaf Ebrahimi                                const VRegister& fa,
7984*f5c631daSSadaf Ebrahimi                                FPDataProcessing3SourceOp op);
7985*f5c631daSSadaf Ebrahimi   void NEONAcrossLanesL(const VRegister& vd,
7986*f5c631daSSadaf Ebrahimi                         const VRegister& vn,
7987*f5c631daSSadaf Ebrahimi                         NEONAcrossLanesOp op);
7988*f5c631daSSadaf Ebrahimi   void NEONAcrossLanes(const VRegister& vd,
7989*f5c631daSSadaf Ebrahimi                        const VRegister& vn,
7990*f5c631daSSadaf Ebrahimi                        NEONAcrossLanesOp op,
7991*f5c631daSSadaf Ebrahimi                        Instr op_half);
7992*f5c631daSSadaf Ebrahimi   void NEONModifiedImmShiftLsl(const VRegister& vd,
7993*f5c631daSSadaf Ebrahimi                                const int imm8,
7994*f5c631daSSadaf Ebrahimi                                const int left_shift,
7995*f5c631daSSadaf Ebrahimi                                NEONModifiedImmediateOp op);
7996*f5c631daSSadaf Ebrahimi   void NEONModifiedImmShiftMsl(const VRegister& vd,
7997*f5c631daSSadaf Ebrahimi                                const int imm8,
7998*f5c631daSSadaf Ebrahimi                                const int shift_amount,
7999*f5c631daSSadaf Ebrahimi                                NEONModifiedImmediateOp op);
8000*f5c631daSSadaf Ebrahimi   void NEONFP2Same(const VRegister& vd, const VRegister& vn, Instr vop);
8001*f5c631daSSadaf Ebrahimi   void NEON3Same(const VRegister& vd,
8002*f5c631daSSadaf Ebrahimi                  const VRegister& vn,
8003*f5c631daSSadaf Ebrahimi                  const VRegister& vm,
8004*f5c631daSSadaf Ebrahimi                  NEON3SameOp vop);
8005*f5c631daSSadaf Ebrahimi   void NEON3SameFP16(const VRegister& vd,
8006*f5c631daSSadaf Ebrahimi                      const VRegister& vn,
8007*f5c631daSSadaf Ebrahimi                      const VRegister& vm,
8008*f5c631daSSadaf Ebrahimi                      Instr op);
8009*f5c631daSSadaf Ebrahimi   void NEONFP3Same(const VRegister& vd,
8010*f5c631daSSadaf Ebrahimi                    const VRegister& vn,
8011*f5c631daSSadaf Ebrahimi                    const VRegister& vm,
8012*f5c631daSSadaf Ebrahimi                    Instr op);
8013*f5c631daSSadaf Ebrahimi   void NEON3DifferentL(const VRegister& vd,
8014*f5c631daSSadaf Ebrahimi                        const VRegister& vn,
8015*f5c631daSSadaf Ebrahimi                        const VRegister& vm,
8016*f5c631daSSadaf Ebrahimi                        NEON3DifferentOp vop);
8017*f5c631daSSadaf Ebrahimi   void NEON3DifferentW(const VRegister& vd,
8018*f5c631daSSadaf Ebrahimi                        const VRegister& vn,
8019*f5c631daSSadaf Ebrahimi                        const VRegister& vm,
8020*f5c631daSSadaf Ebrahimi                        NEON3DifferentOp vop);
8021*f5c631daSSadaf Ebrahimi   void NEON3DifferentHN(const VRegister& vd,
8022*f5c631daSSadaf Ebrahimi                         const VRegister& vn,
8023*f5c631daSSadaf Ebrahimi                         const VRegister& vm,
8024*f5c631daSSadaf Ebrahimi                         NEON3DifferentOp vop);
8025*f5c631daSSadaf Ebrahimi   void NEONFP2RegMisc(const VRegister& vd,
8026*f5c631daSSadaf Ebrahimi                       const VRegister& vn,
8027*f5c631daSSadaf Ebrahimi                       NEON2RegMiscOp vop,
8028*f5c631daSSadaf Ebrahimi                       double value = 0.0);
8029*f5c631daSSadaf Ebrahimi   void NEONFP2RegMiscFP16(const VRegister& vd,
8030*f5c631daSSadaf Ebrahimi                           const VRegister& vn,
8031*f5c631daSSadaf Ebrahimi                           NEON2RegMiscFP16Op vop,
8032*f5c631daSSadaf Ebrahimi                           double value = 0.0);
8033*f5c631daSSadaf Ebrahimi   void NEON2RegMisc(const VRegister& vd,
8034*f5c631daSSadaf Ebrahimi                     const VRegister& vn,
8035*f5c631daSSadaf Ebrahimi                     NEON2RegMiscOp vop,
8036*f5c631daSSadaf Ebrahimi                     int value = 0);
8037*f5c631daSSadaf Ebrahimi   void NEONFP2RegMisc(const VRegister& vd, const VRegister& vn, Instr op);
8038*f5c631daSSadaf Ebrahimi   void NEONFP2RegMiscFP16(const VRegister& vd, const VRegister& vn, Instr op);
8039*f5c631daSSadaf Ebrahimi   void NEONAddlp(const VRegister& vd, const VRegister& vn, NEON2RegMiscOp op);
8040*f5c631daSSadaf Ebrahimi   void NEONPerm(const VRegister& vd,
8041*f5c631daSSadaf Ebrahimi                 const VRegister& vn,
8042*f5c631daSSadaf Ebrahimi                 const VRegister& vm,
8043*f5c631daSSadaf Ebrahimi                 NEONPermOp op);
8044*f5c631daSSadaf Ebrahimi   void NEONFPByElement(const VRegister& vd,
8045*f5c631daSSadaf Ebrahimi                        const VRegister& vn,
8046*f5c631daSSadaf Ebrahimi                        const VRegister& vm,
8047*f5c631daSSadaf Ebrahimi                        int vm_index,
8048*f5c631daSSadaf Ebrahimi                        NEONByIndexedElementOp op,
8049*f5c631daSSadaf Ebrahimi                        NEONByIndexedElementOp op_half);
8050*f5c631daSSadaf Ebrahimi   void NEONByElement(const VRegister& vd,
8051*f5c631daSSadaf Ebrahimi                      const VRegister& vn,
8052*f5c631daSSadaf Ebrahimi                      const VRegister& vm,
8053*f5c631daSSadaf Ebrahimi                      int vm_index,
8054*f5c631daSSadaf Ebrahimi                      NEONByIndexedElementOp op);
8055*f5c631daSSadaf Ebrahimi   void NEONByElementL(const VRegister& vd,
8056*f5c631daSSadaf Ebrahimi                       const VRegister& vn,
8057*f5c631daSSadaf Ebrahimi                       const VRegister& vm,
8058*f5c631daSSadaf Ebrahimi                       int vm_index,
8059*f5c631daSSadaf Ebrahimi                       NEONByIndexedElementOp op);
8060*f5c631daSSadaf Ebrahimi   void NEONShiftImmediate(const VRegister& vd,
8061*f5c631daSSadaf Ebrahimi                           const VRegister& vn,
8062*f5c631daSSadaf Ebrahimi                           NEONShiftImmediateOp op,
8063*f5c631daSSadaf Ebrahimi                           int immh_immb);
8064*f5c631daSSadaf Ebrahimi   void NEONShiftLeftImmediate(const VRegister& vd,
8065*f5c631daSSadaf Ebrahimi                               const VRegister& vn,
8066*f5c631daSSadaf Ebrahimi                               int shift,
8067*f5c631daSSadaf Ebrahimi                               NEONShiftImmediateOp op);
8068*f5c631daSSadaf Ebrahimi   void NEONShiftRightImmediate(const VRegister& vd,
8069*f5c631daSSadaf Ebrahimi                                const VRegister& vn,
8070*f5c631daSSadaf Ebrahimi                                int shift,
8071*f5c631daSSadaf Ebrahimi                                NEONShiftImmediateOp op);
8072*f5c631daSSadaf Ebrahimi   void NEONShiftImmediateL(const VRegister& vd,
8073*f5c631daSSadaf Ebrahimi                            const VRegister& vn,
8074*f5c631daSSadaf Ebrahimi                            int shift,
8075*f5c631daSSadaf Ebrahimi                            NEONShiftImmediateOp op);
8076*f5c631daSSadaf Ebrahimi   void NEONShiftImmediateN(const VRegister& vd,
8077*f5c631daSSadaf Ebrahimi                            const VRegister& vn,
8078*f5c631daSSadaf Ebrahimi                            int shift,
8079*f5c631daSSadaf Ebrahimi                            NEONShiftImmediateOp op);
8080*f5c631daSSadaf Ebrahimi   void NEONXtn(const VRegister& vd, const VRegister& vn, NEON2RegMiscOp vop);
8081*f5c631daSSadaf Ebrahimi 
8082*f5c631daSSadaf Ebrahimi   // If *shift is -1, find values of *imm8 and *shift such that IsInt8(*imm8)
8083*f5c631daSSadaf Ebrahimi   // and *shift is either 0 or 8. Otherwise, leave the values unchanged.
8084*f5c631daSSadaf Ebrahimi   void ResolveSVEImm8Shift(int* imm8, int* shift);
8085*f5c631daSSadaf Ebrahimi 
8086*f5c631daSSadaf Ebrahimi   Instr LoadStoreStructAddrModeField(const MemOperand& addr);
8087*f5c631daSSadaf Ebrahimi 
8088*f5c631daSSadaf Ebrahimi   // Encode the specified MemOperand for the specified access size and scaling
8089*f5c631daSSadaf Ebrahimi   // preference.
8090*f5c631daSSadaf Ebrahimi   Instr LoadStoreMemOperand(const MemOperand& addr,
8091*f5c631daSSadaf Ebrahimi                             unsigned access_size_in_bytes_log2,
8092*f5c631daSSadaf Ebrahimi                             LoadStoreScalingOption option);
8093*f5c631daSSadaf Ebrahimi 
8094*f5c631daSSadaf Ebrahimi   // Link the current (not-yet-emitted) instruction to the specified label, then
8095*f5c631daSSadaf Ebrahimi   // return an offset to be encoded in the instruction. If the label is not yet
8096*f5c631daSSadaf Ebrahimi   // bound, an offset of 0 is returned.
8097*f5c631daSSadaf Ebrahimi   ptrdiff_t LinkAndGetByteOffsetTo(Label* label);
8098*f5c631daSSadaf Ebrahimi   ptrdiff_t LinkAndGetInstructionOffsetTo(Label* label);
8099*f5c631daSSadaf Ebrahimi   ptrdiff_t LinkAndGetPageOffsetTo(Label* label);
8100*f5c631daSSadaf Ebrahimi 
8101*f5c631daSSadaf Ebrahimi   // A common implementation for the LinkAndGet<Type>OffsetTo helpers.
8102*f5c631daSSadaf Ebrahimi   template <int element_shift>
8103*f5c631daSSadaf Ebrahimi   ptrdiff_t LinkAndGetOffsetTo(Label* label);
8104*f5c631daSSadaf Ebrahimi 
8105*f5c631daSSadaf Ebrahimi   // Literal load offset are in words (32-bit).
8106*f5c631daSSadaf Ebrahimi   ptrdiff_t LinkAndGetWordOffsetTo(RawLiteral* literal);
8107*f5c631daSSadaf Ebrahimi 
8108*f5c631daSSadaf Ebrahimi   // Emit the instruction in buffer_.
Emit(Instr instruction)8109*f5c631daSSadaf Ebrahimi   void Emit(Instr instruction) {
8110*f5c631daSSadaf Ebrahimi     VIXL_STATIC_ASSERT(sizeof(instruction) == kInstructionSize);
8111*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(AllowAssembler());
8112*f5c631daSSadaf Ebrahimi     GetBuffer()->Emit32(instruction);
8113*f5c631daSSadaf Ebrahimi   }
8114*f5c631daSSadaf Ebrahimi 
8115*f5c631daSSadaf Ebrahimi   PositionIndependentCodeOption pic_;
8116*f5c631daSSadaf Ebrahimi 
8117*f5c631daSSadaf Ebrahimi   CPUFeatures cpu_features_;
8118*f5c631daSSadaf Ebrahimi };
8119*f5c631daSSadaf Ebrahimi 
8120*f5c631daSSadaf Ebrahimi 
8121*f5c631daSSadaf Ebrahimi template <typename T>
UpdateValue(T new_value,const Assembler * assembler)8122*f5c631daSSadaf Ebrahimi void Literal<T>::UpdateValue(T new_value, const Assembler* assembler) {
8123*f5c631daSSadaf Ebrahimi   return UpdateValue(new_value,
8124*f5c631daSSadaf Ebrahimi                      assembler->GetBuffer().GetStartAddress<uint8_t*>());
8125*f5c631daSSadaf Ebrahimi }
8126*f5c631daSSadaf Ebrahimi 
8127*f5c631daSSadaf Ebrahimi 
8128*f5c631daSSadaf Ebrahimi template <typename T>
UpdateValue(T high64,T low64,const Assembler * assembler)8129*f5c631daSSadaf Ebrahimi void Literal<T>::UpdateValue(T high64, T low64, const Assembler* assembler) {
8130*f5c631daSSadaf Ebrahimi   return UpdateValue(high64,
8131*f5c631daSSadaf Ebrahimi                      low64,
8132*f5c631daSSadaf Ebrahimi                      assembler->GetBuffer().GetStartAddress<uint8_t*>());
8133*f5c631daSSadaf Ebrahimi }
8134*f5c631daSSadaf Ebrahimi 
8135*f5c631daSSadaf Ebrahimi 
8136*f5c631daSSadaf Ebrahimi }  // namespace aarch64
8137*f5c631daSSadaf Ebrahimi 
8138*f5c631daSSadaf Ebrahimi // Required InvalSet template specialisations.
8139*f5c631daSSadaf Ebrahimi // TODO: These template specialisations should not live in this file.  Move
8140*f5c631daSSadaf Ebrahimi // Label out of the aarch64 namespace in order to share its implementation
8141*f5c631daSSadaf Ebrahimi // later.
8142*f5c631daSSadaf Ebrahimi #define INVAL_SET_TEMPLATE_PARAMETERS                                \
8143*f5c631daSSadaf Ebrahimi   ptrdiff_t, aarch64::Label::kNPreallocatedLinks, ptrdiff_t,         \
8144*f5c631daSSadaf Ebrahimi       aarch64::Label::kInvalidLinkKey, aarch64::Label::kReclaimFrom, \
8145*f5c631daSSadaf Ebrahimi       aarch64::Label::kReclaimFactor
8146*f5c631daSSadaf Ebrahimi template <>
GetKey(const ptrdiff_t & element)8147*f5c631daSSadaf Ebrahimi inline ptrdiff_t InvalSet<INVAL_SET_TEMPLATE_PARAMETERS>::GetKey(
8148*f5c631daSSadaf Ebrahimi     const ptrdiff_t& element) {
8149*f5c631daSSadaf Ebrahimi   return element;
8150*f5c631daSSadaf Ebrahimi }
8151*f5c631daSSadaf Ebrahimi template <>
SetKey(ptrdiff_t * element,ptrdiff_t key)8152*f5c631daSSadaf Ebrahimi inline void InvalSet<INVAL_SET_TEMPLATE_PARAMETERS>::SetKey(ptrdiff_t* element,
8153*f5c631daSSadaf Ebrahimi                                                             ptrdiff_t key) {
8154*f5c631daSSadaf Ebrahimi   *element = key;
8155*f5c631daSSadaf Ebrahimi }
8156*f5c631daSSadaf Ebrahimi #undef INVAL_SET_TEMPLATE_PARAMETERS
8157*f5c631daSSadaf Ebrahimi 
8158*f5c631daSSadaf Ebrahimi }  // namespace vixl
8159*f5c631daSSadaf Ebrahimi 
8160*f5c631daSSadaf Ebrahimi #endif  // VIXL_AARCH64_ASSEMBLER_AARCH64_H_
8161