xref: /aosp_15_r20/external/vixl/src/aarch64/assembler-sve-aarch64.cc (revision f5c631da2f1efdd72b5fd1e20510e4042af13d77)
1*f5c631daSSadaf Ebrahimi // Copyright 2019, 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 #include "assembler-aarch64.h"
28*f5c631daSSadaf Ebrahimi 
29*f5c631daSSadaf Ebrahimi namespace vixl {
30*f5c631daSSadaf Ebrahimi namespace aarch64 {
31*f5c631daSSadaf Ebrahimi 
ResolveSVEImm8Shift(int * imm8,int * shift)32*f5c631daSSadaf Ebrahimi void Assembler::ResolveSVEImm8Shift(int* imm8, int* shift) {
33*f5c631daSSadaf Ebrahimi   if (*shift < 0) {
34*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(*shift == -1);
35*f5c631daSSadaf Ebrahimi     // Derive the shift amount from the immediate.
36*f5c631daSSadaf Ebrahimi     if (IsInt8(*imm8)) {
37*f5c631daSSadaf Ebrahimi       *shift = 0;
38*f5c631daSSadaf Ebrahimi     } else if ((*imm8 % 256) == 0) {
39*f5c631daSSadaf Ebrahimi       *imm8 /= 256;
40*f5c631daSSadaf Ebrahimi       *shift = 8;
41*f5c631daSSadaf Ebrahimi     }
42*f5c631daSSadaf Ebrahimi   }
43*f5c631daSSadaf Ebrahimi 
44*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(IsInt8(*imm8));
45*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((*shift == 0) || (*shift == 8));
46*f5c631daSSadaf Ebrahimi }
47*f5c631daSSadaf Ebrahimi 
48*f5c631daSSadaf Ebrahimi // SVEAddressGeneration.
49*f5c631daSSadaf Ebrahimi 
adr(const ZRegister & zd,const SVEMemOperand & addr)50*f5c631daSSadaf Ebrahimi void Assembler::adr(const ZRegister& zd, const SVEMemOperand& addr) {
51*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
52*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsVectorPlusVector());
53*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(
54*f5c631daSSadaf Ebrahimi       AreSameLaneSize(zd, addr.GetVectorBase(), addr.GetVectorOffset()));
55*f5c631daSSadaf Ebrahimi 
56*f5c631daSSadaf Ebrahimi   int lane_size = zd.GetLaneSizeInBits();
57*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((lane_size == kSRegSize) || (lane_size == kDRegSize));
58*f5c631daSSadaf Ebrahimi 
59*f5c631daSSadaf Ebrahimi   int shift_amount = addr.GetShiftAmount();
60*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((shift_amount >= 0) && (shift_amount <= 3));
61*f5c631daSSadaf Ebrahimi 
62*f5c631daSSadaf Ebrahimi   Instr op = 0xffffffff;
63*f5c631daSSadaf Ebrahimi   Instr msz = shift_amount << 10;
64*f5c631daSSadaf Ebrahimi   SVEOffsetModifier mod = addr.GetOffsetModifier();
65*f5c631daSSadaf Ebrahimi   switch (mod) {
66*f5c631daSSadaf Ebrahimi     case SVE_UXTW:
67*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(lane_size == kDRegSize);
68*f5c631daSSadaf Ebrahimi       op = ADR_z_az_d_u32_scaled;
69*f5c631daSSadaf Ebrahimi       break;
70*f5c631daSSadaf Ebrahimi     case SVE_SXTW:
71*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(lane_size == kDRegSize);
72*f5c631daSSadaf Ebrahimi       op = ADR_z_az_d_s32_scaled;
73*f5c631daSSadaf Ebrahimi       break;
74*f5c631daSSadaf Ebrahimi     case SVE_LSL:
75*f5c631daSSadaf Ebrahimi     case NO_SVE_OFFSET_MODIFIER:
76*f5c631daSSadaf Ebrahimi       op = (lane_size == kSRegSize) ? ADR_z_az_s_same_scaled
77*f5c631daSSadaf Ebrahimi                                     : ADR_z_az_d_same_scaled;
78*f5c631daSSadaf Ebrahimi       break;
79*f5c631daSSadaf Ebrahimi     default:
80*f5c631daSSadaf Ebrahimi       VIXL_UNIMPLEMENTED();
81*f5c631daSSadaf Ebrahimi   }
82*f5c631daSSadaf Ebrahimi   Emit(op | msz | Rd(zd) | Rn(addr.GetVectorBase()) |
83*f5c631daSSadaf Ebrahimi        Rm(addr.GetVectorOffset()));
84*f5c631daSSadaf Ebrahimi }
85*f5c631daSSadaf Ebrahimi 
SVELogicalImmediate(const ZRegister & zdn,uint64_t imm,Instr op)86*f5c631daSSadaf Ebrahimi void Assembler::SVELogicalImmediate(const ZRegister& zdn,
87*f5c631daSSadaf Ebrahimi                                     uint64_t imm,
88*f5c631daSSadaf Ebrahimi                                     Instr op) {
89*f5c631daSSadaf Ebrahimi   unsigned bit_n, imm_s, imm_r;
90*f5c631daSSadaf Ebrahimi   unsigned lane_size = zdn.GetLaneSizeInBits();
91*f5c631daSSadaf Ebrahimi   // Check that the immediate can be encoded in the instruction.
92*f5c631daSSadaf Ebrahimi   if (IsImmLogical(imm, lane_size, &bit_n, &imm_s, &imm_r)) {
93*f5c631daSSadaf Ebrahimi     Emit(op | Rd(zdn) | SVEBitN(bit_n) | SVEImmRotate(imm_r, lane_size) |
94*f5c631daSSadaf Ebrahimi          SVEImmSetBits(imm_s, lane_size));
95*f5c631daSSadaf Ebrahimi   } else {
96*f5c631daSSadaf Ebrahimi     VIXL_UNREACHABLE();
97*f5c631daSSadaf Ebrahimi   }
98*f5c631daSSadaf Ebrahimi }
99*f5c631daSSadaf Ebrahimi 
and_(const ZRegister & zd,const ZRegister & zn,uint64_t imm)100*f5c631daSSadaf Ebrahimi void Assembler::and_(const ZRegister& zd, const ZRegister& zn, uint64_t imm) {
101*f5c631daSSadaf Ebrahimi   USE(zn);
102*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
103*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
104*f5c631daSSadaf Ebrahimi   SVELogicalImmediate(zd, imm, AND_z_zi);
105*f5c631daSSadaf Ebrahimi }
106*f5c631daSSadaf Ebrahimi 
dupm(const ZRegister & zd,uint64_t imm)107*f5c631daSSadaf Ebrahimi void Assembler::dupm(const ZRegister& zd, uint64_t imm) {
108*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
109*f5c631daSSadaf Ebrahimi   // DUPM_z_i is an SVEBroadcastBitmaskImmOp, but its encoding and constraints
110*f5c631daSSadaf Ebrahimi   // are similar enough to SVEBitwiseLogicalWithImm_UnpredicatedOp, that we can
111*f5c631daSSadaf Ebrahimi   // use the logical immediate encoder to get the correct behaviour.
112*f5c631daSSadaf Ebrahimi   SVELogicalImmediate(zd, imm, DUPM_z_i);
113*f5c631daSSadaf Ebrahimi }
114*f5c631daSSadaf Ebrahimi 
eor(const ZRegister & zd,const ZRegister & zn,uint64_t imm)115*f5c631daSSadaf Ebrahimi void Assembler::eor(const ZRegister& zd, const ZRegister& zn, uint64_t imm) {
116*f5c631daSSadaf Ebrahimi   USE(zn);
117*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
118*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
119*f5c631daSSadaf Ebrahimi   SVELogicalImmediate(zd, imm, EOR_z_zi);
120*f5c631daSSadaf Ebrahimi }
121*f5c631daSSadaf Ebrahimi 
orr(const ZRegister & zd,const ZRegister & zn,uint64_t imm)122*f5c631daSSadaf Ebrahimi void Assembler::orr(const ZRegister& zd, const ZRegister& zn, uint64_t imm) {
123*f5c631daSSadaf Ebrahimi   USE(zn);
124*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
125*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
126*f5c631daSSadaf Ebrahimi   SVELogicalImmediate(zd, imm, ORR_z_zi);
127*f5c631daSSadaf Ebrahimi }
128*f5c631daSSadaf Ebrahimi 
129*f5c631daSSadaf Ebrahimi // SVEBitwiseLogicalUnpredicated.
and_(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)130*f5c631daSSadaf Ebrahimi void Assembler::and_(const ZRegister& zd,
131*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
132*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
133*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
134*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeD());
135*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(zd, zn, zm));
136*f5c631daSSadaf Ebrahimi   Emit(AND_z_zz | Rd(zd) | Rn(zn) | Rm(zm));
137*f5c631daSSadaf Ebrahimi }
138*f5c631daSSadaf Ebrahimi 
bic(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)139*f5c631daSSadaf Ebrahimi void Assembler::bic(const ZRegister& zd,
140*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
141*f5c631daSSadaf Ebrahimi                     const ZRegister& zm) {
142*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
143*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeD());
144*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(zd, zn, zm));
145*f5c631daSSadaf Ebrahimi   Emit(BIC_z_zz | Rd(zd) | Rn(zn) | Rm(zm));
146*f5c631daSSadaf Ebrahimi }
147*f5c631daSSadaf Ebrahimi 
eor(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)148*f5c631daSSadaf Ebrahimi void Assembler::eor(const ZRegister& zd,
149*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
150*f5c631daSSadaf Ebrahimi                     const ZRegister& zm) {
151*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
152*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeD());
153*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(zd, zn, zm));
154*f5c631daSSadaf Ebrahimi   Emit(EOR_z_zz | Rd(zd) | Rn(zn) | Rm(zm));
155*f5c631daSSadaf Ebrahimi }
156*f5c631daSSadaf Ebrahimi 
orr(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)157*f5c631daSSadaf Ebrahimi void Assembler::orr(const ZRegister& zd,
158*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
159*f5c631daSSadaf Ebrahimi                     const ZRegister& zm) {
160*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
161*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeD());
162*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(zd, zn, zm));
163*f5c631daSSadaf Ebrahimi   Emit(ORR_z_zz | Rd(zd) | Rn(zn) | Rm(zm));
164*f5c631daSSadaf Ebrahimi }
165*f5c631daSSadaf Ebrahimi 
166*f5c631daSSadaf Ebrahimi // SVEBitwiseShiftPredicated.
167*f5c631daSSadaf Ebrahimi 
SVEBitwiseShiftImmediatePred(const ZRegister & zdn,const PRegisterM & pg,Instr encoded_imm_and_tsz,Instr op)168*f5c631daSSadaf Ebrahimi void Assembler::SVEBitwiseShiftImmediatePred(const ZRegister& zdn,
169*f5c631daSSadaf Ebrahimi                                              const PRegisterM& pg,
170*f5c631daSSadaf Ebrahimi                                              Instr encoded_imm_and_tsz,
171*f5c631daSSadaf Ebrahimi                                              Instr op) {
172*f5c631daSSadaf Ebrahimi   Instr tszl_and_imm = ExtractUnsignedBitfield32(4, 0, encoded_imm_and_tsz)
173*f5c631daSSadaf Ebrahimi                        << 5;
174*f5c631daSSadaf Ebrahimi   Instr tszh = ExtractUnsignedBitfield32(6, 5, encoded_imm_and_tsz) << 22;
175*f5c631daSSadaf Ebrahimi   Emit(op | tszh | tszl_and_imm | PgLow8(pg) | Rd(zdn));
176*f5c631daSSadaf Ebrahimi }
177*f5c631daSSadaf Ebrahimi 
asr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,int shift)178*f5c631daSSadaf Ebrahimi void Assembler::asr(const ZRegister& zd,
179*f5c631daSSadaf Ebrahimi                     const PRegisterM& pg,
180*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
181*f5c631daSSadaf Ebrahimi                     int shift) {
182*f5c631daSSadaf Ebrahimi   // ASR <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, #<const>
183*f5c631daSSadaf Ebrahimi   //  0000 0100 ..00 0000 100. .... .... ....
184*f5c631daSSadaf Ebrahimi   //  tszh<23:22> | opc<19:18> = 00 | L<17> = 0 | U<16> = 0 | Pg<12:10> |
185*f5c631daSSadaf Ebrahimi   //  tszl<9:8> | imm3<7:5> | Zdn<4:0>
186*f5c631daSSadaf Ebrahimi 
187*f5c631daSSadaf Ebrahimi   USE(zn);
188*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
189*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
190*f5c631daSSadaf Ebrahimi   Instr encoded_imm =
191*f5c631daSSadaf Ebrahimi       EncodeSVEShiftRightImmediate(shift, zd.GetLaneSizeInBits());
192*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediatePred(zd, pg, encoded_imm, ASR_z_p_zi);
193*f5c631daSSadaf Ebrahimi }
194*f5c631daSSadaf Ebrahimi 
asr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)195*f5c631daSSadaf Ebrahimi void Assembler::asr(const ZRegister& zd,
196*f5c631daSSadaf Ebrahimi                     const PRegisterM& pg,
197*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
198*f5c631daSSadaf Ebrahimi                     const ZRegister& zm) {
199*f5c631daSSadaf Ebrahimi   // ASR <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.D
200*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 1000 100. .... .... ....
201*f5c631daSSadaf Ebrahimi   //  size<23:22> | R<18> = 0 | L<17> = 0 | U<16> = 0 | Pg<12:10> | Zm<9:5> |
202*f5c631daSSadaf Ebrahimi   //  Zdn<4:0>
203*f5c631daSSadaf Ebrahimi 
204*f5c631daSSadaf Ebrahimi   USE(zn);
205*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
206*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
207*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm) ||
208*f5c631daSSadaf Ebrahimi               ((zm.GetLaneSizeInBytes() == kDRegSizeInBytes) &&
209*f5c631daSSadaf Ebrahimi                (zd.GetLaneSizeInBytes() != kDRegSizeInBytes)));
210*f5c631daSSadaf Ebrahimi   Instr op = ASR_z_p_zw;
211*f5c631daSSadaf Ebrahimi   if (AreSameLaneSize(zd, zn, zm)) {
212*f5c631daSSadaf Ebrahimi     op = ASR_z_p_zz;
213*f5c631daSSadaf Ebrahimi   }
214*f5c631daSSadaf Ebrahimi   Emit(op | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
215*f5c631daSSadaf Ebrahimi }
216*f5c631daSSadaf Ebrahimi 
asrd(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,int shift)217*f5c631daSSadaf Ebrahimi void Assembler::asrd(const ZRegister& zd,
218*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
219*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
220*f5c631daSSadaf Ebrahimi                      int shift) {
221*f5c631daSSadaf Ebrahimi   // ASRD <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, #<const>
222*f5c631daSSadaf Ebrahimi   //  0000 0100 ..00 0100 100. .... .... ....
223*f5c631daSSadaf Ebrahimi   //  tszh<23:22> | opc<19:18> = 01 | L<17> = 0 | U<16> = 0 | Pg<12:10> |
224*f5c631daSSadaf Ebrahimi   //  tszl<9:8> | imm3<7:5> | Zdn<4:0>
225*f5c631daSSadaf Ebrahimi 
226*f5c631daSSadaf Ebrahimi   USE(zn);
227*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
228*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
229*f5c631daSSadaf Ebrahimi 
230*f5c631daSSadaf Ebrahimi   Instr encoded_imm =
231*f5c631daSSadaf Ebrahimi       EncodeSVEShiftRightImmediate(shift, zd.GetLaneSizeInBits());
232*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediatePred(zd, pg, encoded_imm, ASRD_z_p_zi);
233*f5c631daSSadaf Ebrahimi }
234*f5c631daSSadaf Ebrahimi 
asrr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)235*f5c631daSSadaf Ebrahimi void Assembler::asrr(const ZRegister& zd,
236*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
237*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
238*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
239*f5c631daSSadaf Ebrahimi   // ASRR <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
240*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 0100 100. .... .... ....
241*f5c631daSSadaf Ebrahimi   //  size<23:22> | R<18> = 1 | L<17> = 0 | U<16> = 0 | Pg<12:10> | Zm<9:5> |
242*f5c631daSSadaf Ebrahimi   //  Zdn<4:0>
243*f5c631daSSadaf Ebrahimi 
244*f5c631daSSadaf Ebrahimi   USE(zn);
245*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
246*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
247*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
248*f5c631daSSadaf Ebrahimi 
249*f5c631daSSadaf Ebrahimi   Emit(ASRR_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
250*f5c631daSSadaf Ebrahimi }
251*f5c631daSSadaf Ebrahimi 
lsl(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,int shift)252*f5c631daSSadaf Ebrahimi void Assembler::lsl(const ZRegister& zd,
253*f5c631daSSadaf Ebrahimi                     const PRegisterM& pg,
254*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
255*f5c631daSSadaf Ebrahimi                     int shift) {
256*f5c631daSSadaf Ebrahimi   // LSL <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, #<const>
257*f5c631daSSadaf Ebrahimi   //  0000 0100 ..00 0011 100. .... .... ....
258*f5c631daSSadaf Ebrahimi   //  tszh<23:22> | opc<19:18> = 00 | L<17> = 1 | U<16> = 1 | Pg<12:10> |
259*f5c631daSSadaf Ebrahimi   //  tszl<9:8> | imm3<7:5> | Zdn<4:0>
260*f5c631daSSadaf Ebrahimi 
261*f5c631daSSadaf Ebrahimi   USE(zn);
262*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
263*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
264*f5c631daSSadaf Ebrahimi 
265*f5c631daSSadaf Ebrahimi   Instr encoded_imm =
266*f5c631daSSadaf Ebrahimi       EncodeSVEShiftLeftImmediate(shift, zd.GetLaneSizeInBits());
267*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediatePred(zd, pg, encoded_imm, LSL_z_p_zi);
268*f5c631daSSadaf Ebrahimi }
269*f5c631daSSadaf Ebrahimi 
lsl(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)270*f5c631daSSadaf Ebrahimi void Assembler::lsl(const ZRegister& zd,
271*f5c631daSSadaf Ebrahimi                     const PRegisterM& pg,
272*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
273*f5c631daSSadaf Ebrahimi                     const ZRegister& zm) {
274*f5c631daSSadaf Ebrahimi   // LSL <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.D
275*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 1011 100. .... .... ....
276*f5c631daSSadaf Ebrahimi   //  size<23:22> | R<18> = 0 | L<17> = 1 | U<16> = 1 | Pg<12:10> | Zm<9:5> |
277*f5c631daSSadaf Ebrahimi   //  Zdn<4:0>
278*f5c631daSSadaf Ebrahimi 
279*f5c631daSSadaf Ebrahimi   USE(zn);
280*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
281*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
282*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm) ||
283*f5c631daSSadaf Ebrahimi               ((zm.GetLaneSizeInBytes() == kDRegSizeInBytes) &&
284*f5c631daSSadaf Ebrahimi                (zd.GetLaneSizeInBytes() != kDRegSizeInBytes)));
285*f5c631daSSadaf Ebrahimi   Instr op = LSL_z_p_zw;
286*f5c631daSSadaf Ebrahimi   if (AreSameLaneSize(zd, zn, zm)) {
287*f5c631daSSadaf Ebrahimi     op = LSL_z_p_zz;
288*f5c631daSSadaf Ebrahimi   }
289*f5c631daSSadaf Ebrahimi   Emit(op | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
290*f5c631daSSadaf Ebrahimi }
291*f5c631daSSadaf Ebrahimi 
lslr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)292*f5c631daSSadaf Ebrahimi void Assembler::lslr(const ZRegister& zd,
293*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
294*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
295*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
296*f5c631daSSadaf Ebrahimi   // LSLR <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
297*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 0111 100. .... .... ....
298*f5c631daSSadaf Ebrahimi   //  size<23:22> | R<18> = 1 | L<17> = 1 | U<16> = 1 | Pg<12:10> | Zm<9:5> |
299*f5c631daSSadaf Ebrahimi   //  Zdn<4:0>
300*f5c631daSSadaf Ebrahimi 
301*f5c631daSSadaf Ebrahimi   USE(zn);
302*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
303*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
304*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
305*f5c631daSSadaf Ebrahimi 
306*f5c631daSSadaf Ebrahimi   Emit(LSLR_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
307*f5c631daSSadaf Ebrahimi }
308*f5c631daSSadaf Ebrahimi 
lsr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,int shift)309*f5c631daSSadaf Ebrahimi void Assembler::lsr(const ZRegister& zd,
310*f5c631daSSadaf Ebrahimi                     const PRegisterM& pg,
311*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
312*f5c631daSSadaf Ebrahimi                     int shift) {
313*f5c631daSSadaf Ebrahimi   // LSR <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, #<const>
314*f5c631daSSadaf Ebrahimi   //  0000 0100 ..00 0001 100. .... .... ....
315*f5c631daSSadaf Ebrahimi   //  tszh<23:22> | opc<19:18> = 00 | L<17> = 0 | U<16> = 1 | Pg<12:10> |
316*f5c631daSSadaf Ebrahimi   //  tszl<9:8> | imm3<7:5> | Zdn<4:0>
317*f5c631daSSadaf Ebrahimi 
318*f5c631daSSadaf Ebrahimi   USE(zn);
319*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
320*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
321*f5c631daSSadaf Ebrahimi 
322*f5c631daSSadaf Ebrahimi   Instr encoded_imm =
323*f5c631daSSadaf Ebrahimi       EncodeSVEShiftRightImmediate(shift, zd.GetLaneSizeInBits());
324*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediatePred(zd, pg, encoded_imm, LSR_z_p_zi);
325*f5c631daSSadaf Ebrahimi }
326*f5c631daSSadaf Ebrahimi 
lsr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)327*f5c631daSSadaf Ebrahimi void Assembler::lsr(const ZRegister& zd,
328*f5c631daSSadaf Ebrahimi                     const PRegisterM& pg,
329*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
330*f5c631daSSadaf Ebrahimi                     const ZRegister& zm) {
331*f5c631daSSadaf Ebrahimi   // LSR <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.D
332*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 1001 100. .... .... ....
333*f5c631daSSadaf Ebrahimi   //  size<23:22> | R<18> = 0 | L<17> = 0 | U<16> = 1 | Pg<12:10> | Zm<9:5> |
334*f5c631daSSadaf Ebrahimi   //  Zdn<4:0>
335*f5c631daSSadaf Ebrahimi 
336*f5c631daSSadaf Ebrahimi   USE(zn);
337*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
338*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
339*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm) ||
340*f5c631daSSadaf Ebrahimi               ((zm.GetLaneSizeInBytes() == kDRegSizeInBytes) &&
341*f5c631daSSadaf Ebrahimi                (zd.GetLaneSizeInBytes() != kDRegSizeInBytes)));
342*f5c631daSSadaf Ebrahimi   Instr op = LSR_z_p_zw;
343*f5c631daSSadaf Ebrahimi   if (AreSameLaneSize(zd, zn, zm)) {
344*f5c631daSSadaf Ebrahimi     op = LSR_z_p_zz;
345*f5c631daSSadaf Ebrahimi   }
346*f5c631daSSadaf Ebrahimi   Emit(op | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
347*f5c631daSSadaf Ebrahimi }
348*f5c631daSSadaf Ebrahimi 
lsrr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)349*f5c631daSSadaf Ebrahimi void Assembler::lsrr(const ZRegister& zd,
350*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
351*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
352*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
353*f5c631daSSadaf Ebrahimi   // LSRR <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
354*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 0101 100. .... .... ....
355*f5c631daSSadaf Ebrahimi   //  size<23:22> | R<18> = 1 | L<17> = 0 | U<16> = 1 | Pg<12:10> | Zm<9:5> |
356*f5c631daSSadaf Ebrahimi   //  Zdn<4:0>
357*f5c631daSSadaf Ebrahimi 
358*f5c631daSSadaf Ebrahimi   USE(zn);
359*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
360*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
361*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
362*f5c631daSSadaf Ebrahimi 
363*f5c631daSSadaf Ebrahimi   Emit(LSRR_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
364*f5c631daSSadaf Ebrahimi }
365*f5c631daSSadaf Ebrahimi 
366*f5c631daSSadaf Ebrahimi // SVEBitwiseShiftUnpredicated.
367*f5c631daSSadaf Ebrahimi 
EncodeSVEShiftLeftImmediate(int shift,int lane_size_in_bits)368*f5c631daSSadaf Ebrahimi Instr Assembler::EncodeSVEShiftLeftImmediate(int shift, int lane_size_in_bits) {
369*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((shift >= 0) && (shift < lane_size_in_bits));
370*f5c631daSSadaf Ebrahimi   return lane_size_in_bits + shift;
371*f5c631daSSadaf Ebrahimi }
372*f5c631daSSadaf Ebrahimi 
EncodeSVEShiftRightImmediate(int shift,int lane_size_in_bits)373*f5c631daSSadaf Ebrahimi Instr Assembler::EncodeSVEShiftRightImmediate(int shift,
374*f5c631daSSadaf Ebrahimi                                               int lane_size_in_bits) {
375*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((shift > 0) && (shift <= lane_size_in_bits));
376*f5c631daSSadaf Ebrahimi   return (2 * lane_size_in_bits) - shift;
377*f5c631daSSadaf Ebrahimi }
378*f5c631daSSadaf Ebrahimi 
SVEBitwiseShiftImmediate(const ZRegister & zd,const ZRegister & zn,Instr encoded_imm_and_tsz,Instr op)379*f5c631daSSadaf Ebrahimi void Assembler::SVEBitwiseShiftImmediate(const ZRegister& zd,
380*f5c631daSSadaf Ebrahimi                                          const ZRegister& zn,
381*f5c631daSSadaf Ebrahimi                                          Instr encoded_imm_and_tsz,
382*f5c631daSSadaf Ebrahimi                                          Instr op) {
383*f5c631daSSadaf Ebrahimi   Instr tszl_and_imm = ExtractUnsignedBitfield32(4, 0, encoded_imm_and_tsz)
384*f5c631daSSadaf Ebrahimi                        << 16;
385*f5c631daSSadaf Ebrahimi   Instr tszh = ExtractUnsignedBitfield32(6, 5, encoded_imm_and_tsz) << 22;
386*f5c631daSSadaf Ebrahimi   Emit(op | tszh | tszl_and_imm | Rd(zd) | Rn(zn));
387*f5c631daSSadaf Ebrahimi }
388*f5c631daSSadaf Ebrahimi 
asr(const ZRegister & zd,const ZRegister & zn,int shift)389*f5c631daSSadaf Ebrahimi void Assembler::asr(const ZRegister& zd, const ZRegister& zn, int shift) {
390*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
391*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
392*f5c631daSSadaf Ebrahimi   Instr encoded_imm =
393*f5c631daSSadaf Ebrahimi       EncodeSVEShiftRightImmediate(shift, zd.GetLaneSizeInBits());
394*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediate(zd, zn, encoded_imm, ASR_z_zi);
395*f5c631daSSadaf Ebrahimi }
396*f5c631daSSadaf Ebrahimi 
asr(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)397*f5c631daSSadaf Ebrahimi void Assembler::asr(const ZRegister& zd,
398*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
399*f5c631daSSadaf Ebrahimi                     const ZRegister& zm) {
400*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
401*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
402*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kDRegSizeInBytes);
403*f5c631daSSadaf Ebrahimi 
404*f5c631daSSadaf Ebrahimi   Emit(ASR_z_zw | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
405*f5c631daSSadaf Ebrahimi }
406*f5c631daSSadaf Ebrahimi 
lsl(const ZRegister & zd,const ZRegister & zn,int shift)407*f5c631daSSadaf Ebrahimi void Assembler::lsl(const ZRegister& zd, const ZRegister& zn, int shift) {
408*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
409*f5c631daSSadaf Ebrahimi   Instr encoded_imm =
410*f5c631daSSadaf Ebrahimi       EncodeSVEShiftLeftImmediate(shift, zd.GetLaneSizeInBits());
411*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediate(zd, zn, encoded_imm, LSL_z_zi);
412*f5c631daSSadaf Ebrahimi }
413*f5c631daSSadaf Ebrahimi 
lsl(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)414*f5c631daSSadaf Ebrahimi void Assembler::lsl(const ZRegister& zd,
415*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
416*f5c631daSSadaf Ebrahimi                     const ZRegister& zm) {
417*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
418*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
419*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kDRegSizeInBytes);
420*f5c631daSSadaf Ebrahimi 
421*f5c631daSSadaf Ebrahimi   Emit(LSL_z_zw | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
422*f5c631daSSadaf Ebrahimi }
423*f5c631daSSadaf Ebrahimi 
lsr(const ZRegister & zd,const ZRegister & zn,int shift)424*f5c631daSSadaf Ebrahimi void Assembler::lsr(const ZRegister& zd, const ZRegister& zn, int shift) {
425*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
426*f5c631daSSadaf Ebrahimi   Instr encoded_imm =
427*f5c631daSSadaf Ebrahimi       EncodeSVEShiftRightImmediate(shift, zd.GetLaneSizeInBits());
428*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediate(zd, zn, encoded_imm, LSR_z_zi);
429*f5c631daSSadaf Ebrahimi }
430*f5c631daSSadaf Ebrahimi 
lsr(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)431*f5c631daSSadaf Ebrahimi void Assembler::lsr(const ZRegister& zd,
432*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
433*f5c631daSSadaf Ebrahimi                     const ZRegister& zm) {
434*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
435*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
436*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kDRegSizeInBytes);
437*f5c631daSSadaf Ebrahimi 
438*f5c631daSSadaf Ebrahimi   Emit(LSR_z_zw | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
439*f5c631daSSadaf Ebrahimi }
440*f5c631daSSadaf Ebrahimi 
441*f5c631daSSadaf Ebrahimi // SVEElementCount.
442*f5c631daSSadaf Ebrahimi 
443*f5c631daSSadaf Ebrahimi #define VIXL_SVE_INC_DEC_LIST(V) \
444*f5c631daSSadaf Ebrahimi   V(cntb, CNTB_r_s)              \
445*f5c631daSSadaf Ebrahimi   V(cnth, CNTH_r_s)              \
446*f5c631daSSadaf Ebrahimi   V(cntw, CNTW_r_s)              \
447*f5c631daSSadaf Ebrahimi   V(cntd, CNTD_r_s)              \
448*f5c631daSSadaf Ebrahimi   V(decb, DECB_r_rs)             \
449*f5c631daSSadaf Ebrahimi   V(dech, DECH_r_rs)             \
450*f5c631daSSadaf Ebrahimi   V(decw, DECW_r_rs)             \
451*f5c631daSSadaf Ebrahimi   V(decd, DECD_r_rs)             \
452*f5c631daSSadaf Ebrahimi   V(incb, INCB_r_rs)             \
453*f5c631daSSadaf Ebrahimi   V(inch, INCH_r_rs)             \
454*f5c631daSSadaf Ebrahimi   V(incw, INCW_r_rs)             \
455*f5c631daSSadaf Ebrahimi   V(incd, INCD_r_rs)             \
456*f5c631daSSadaf Ebrahimi   V(sqdecb, SQDECB_r_rs_x)       \
457*f5c631daSSadaf Ebrahimi   V(sqdech, SQDECH_r_rs_x)       \
458*f5c631daSSadaf Ebrahimi   V(sqdecw, SQDECW_r_rs_x)       \
459*f5c631daSSadaf Ebrahimi   V(sqdecd, SQDECD_r_rs_x)       \
460*f5c631daSSadaf Ebrahimi   V(sqincb, SQINCB_r_rs_x)       \
461*f5c631daSSadaf Ebrahimi   V(sqinch, SQINCH_r_rs_x)       \
462*f5c631daSSadaf Ebrahimi   V(sqincw, SQINCW_r_rs_x)       \
463*f5c631daSSadaf Ebrahimi   V(sqincd, SQINCD_r_rs_x)
464*f5c631daSSadaf Ebrahimi 
465*f5c631daSSadaf Ebrahimi #define VIXL_DEFINE_ASM_FUNC(FN, OP)                                     \
466*f5c631daSSadaf Ebrahimi   void Assembler::FN(const Register& rdn, int pattern, int multiplier) { \
467*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));                              \
468*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(rdn.IsX());                                              \
469*f5c631daSSadaf Ebrahimi     Emit(OP | Rd(rdn) | ImmSVEPredicateConstraint(pattern) |             \
470*f5c631daSSadaf Ebrahimi          ImmUnsignedField<19, 16>(multiplier - 1));                      \
471*f5c631daSSadaf Ebrahimi   }
472*f5c631daSSadaf Ebrahimi VIXL_SVE_INC_DEC_LIST(VIXL_DEFINE_ASM_FUNC)
473*f5c631daSSadaf Ebrahimi #undef VIXL_DEFINE_ASM_FUNC
474*f5c631daSSadaf Ebrahimi 
475*f5c631daSSadaf Ebrahimi #define VIXL_SVE_UQINC_UQDEC_LIST(V)                      \
476*f5c631daSSadaf Ebrahimi   V(uqdecb, (rdn.IsX() ? UQDECB_r_rs_x : UQDECB_r_rs_uw)) \
477*f5c631daSSadaf Ebrahimi   V(uqdech, (rdn.IsX() ? UQDECH_r_rs_x : UQDECH_r_rs_uw)) \
478*f5c631daSSadaf Ebrahimi   V(uqdecw, (rdn.IsX() ? UQDECW_r_rs_x : UQDECW_r_rs_uw)) \
479*f5c631daSSadaf Ebrahimi   V(uqdecd, (rdn.IsX() ? UQDECD_r_rs_x : UQDECD_r_rs_uw)) \
480*f5c631daSSadaf Ebrahimi   V(uqincb, (rdn.IsX() ? UQINCB_r_rs_x : UQINCB_r_rs_uw)) \
481*f5c631daSSadaf Ebrahimi   V(uqinch, (rdn.IsX() ? UQINCH_r_rs_x : UQINCH_r_rs_uw)) \
482*f5c631daSSadaf Ebrahimi   V(uqincw, (rdn.IsX() ? UQINCW_r_rs_x : UQINCW_r_rs_uw)) \
483*f5c631daSSadaf Ebrahimi   V(uqincd, (rdn.IsX() ? UQINCD_r_rs_x : UQINCD_r_rs_uw))
484*f5c631daSSadaf Ebrahimi 
485*f5c631daSSadaf Ebrahimi #define VIXL_DEFINE_ASM_FUNC(FN, OP)                                     \
486*f5c631daSSadaf Ebrahimi   void Assembler::FN(const Register& rdn, int pattern, int multiplier) { \
487*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));                              \
488*f5c631daSSadaf Ebrahimi     Emit(OP | Rd(rdn) | ImmSVEPredicateConstraint(pattern) |             \
489*f5c631daSSadaf Ebrahimi          ImmUnsignedField<19, 16>(multiplier - 1));                      \
490*f5c631daSSadaf Ebrahimi   }
VIXL_SVE_UQINC_UQDEC_LIST(VIXL_DEFINE_ASM_FUNC)491*f5c631daSSadaf Ebrahimi VIXL_SVE_UQINC_UQDEC_LIST(VIXL_DEFINE_ASM_FUNC)
492*f5c631daSSadaf Ebrahimi #undef VIXL_DEFINE_ASM_FUNC
493*f5c631daSSadaf Ebrahimi 
494*f5c631daSSadaf Ebrahimi #define VIXL_SVE_SQX_INC_DEC_LIST(V) \
495*f5c631daSSadaf Ebrahimi   V(sqdecb, SQDECB)                  \
496*f5c631daSSadaf Ebrahimi   V(sqdech, SQDECH)                  \
497*f5c631daSSadaf Ebrahimi   V(sqdecw, SQDECW)                  \
498*f5c631daSSadaf Ebrahimi   V(sqdecd, SQDECD)                  \
499*f5c631daSSadaf Ebrahimi   V(sqincb, SQINCB)                  \
500*f5c631daSSadaf Ebrahimi   V(sqinch, SQINCH)                  \
501*f5c631daSSadaf Ebrahimi   V(sqincw, SQINCW)                  \
502*f5c631daSSadaf Ebrahimi   V(sqincd, SQINCD)
503*f5c631daSSadaf Ebrahimi 
504*f5c631daSSadaf Ebrahimi #define VIXL_DEFINE_ASM_FUNC(FN, OP)                                  \
505*f5c631daSSadaf Ebrahimi   void Assembler::FN(const Register& xd,                              \
506*f5c631daSSadaf Ebrahimi                      const Register& wn,                              \
507*f5c631daSSadaf Ebrahimi                      int pattern,                                     \
508*f5c631daSSadaf Ebrahimi                      int multiplier) {                                \
509*f5c631daSSadaf Ebrahimi     USE(wn);                                                          \
510*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));                           \
511*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(wn.IsW() && xd.Is(wn.X()));                           \
512*f5c631daSSadaf Ebrahimi     Emit(OP##_r_rs_sx | Rd(xd) | ImmSVEPredicateConstraint(pattern) | \
513*f5c631daSSadaf Ebrahimi          ImmUnsignedField<19, 16>(multiplier - 1));                   \
514*f5c631daSSadaf Ebrahimi   }
515*f5c631daSSadaf Ebrahimi VIXL_SVE_SQX_INC_DEC_LIST(VIXL_DEFINE_ASM_FUNC)
516*f5c631daSSadaf Ebrahimi #undef VIXL_DEFINE_ASM_FUNC
517*f5c631daSSadaf Ebrahimi 
518*f5c631daSSadaf Ebrahimi #define VIXL_SVE_INC_DEC_VEC_LIST(V) \
519*f5c631daSSadaf Ebrahimi   V(dech, DEC, H)                    \
520*f5c631daSSadaf Ebrahimi   V(decw, DEC, W)                    \
521*f5c631daSSadaf Ebrahimi   V(decd, DEC, D)                    \
522*f5c631daSSadaf Ebrahimi   V(inch, INC, H)                    \
523*f5c631daSSadaf Ebrahimi   V(incw, INC, W)                    \
524*f5c631daSSadaf Ebrahimi   V(incd, INC, D)                    \
525*f5c631daSSadaf Ebrahimi   V(sqdech, SQDEC, H)                \
526*f5c631daSSadaf Ebrahimi   V(sqdecw, SQDEC, W)                \
527*f5c631daSSadaf Ebrahimi   V(sqdecd, SQDEC, D)                \
528*f5c631daSSadaf Ebrahimi   V(sqinch, SQINC, H)                \
529*f5c631daSSadaf Ebrahimi   V(sqincw, SQINC, W)                \
530*f5c631daSSadaf Ebrahimi   V(sqincd, SQINC, D)                \
531*f5c631daSSadaf Ebrahimi   V(uqdech, UQDEC, H)                \
532*f5c631daSSadaf Ebrahimi   V(uqdecw, UQDEC, W)                \
533*f5c631daSSadaf Ebrahimi   V(uqdecd, UQDEC, D)                \
534*f5c631daSSadaf Ebrahimi   V(uqinch, UQINC, H)                \
535*f5c631daSSadaf Ebrahimi   V(uqincw, UQINC, W)                \
536*f5c631daSSadaf Ebrahimi   V(uqincd, UQINC, D)
537*f5c631daSSadaf Ebrahimi 
538*f5c631daSSadaf Ebrahimi #define VIXL_DEFINE_ASM_FUNC(FN, OP, T)                                   \
539*f5c631daSSadaf Ebrahimi   void Assembler::FN(const ZRegister& zdn, int pattern, int multiplier) { \
540*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));                               \
541*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zdn.GetLaneSizeInBytes() == k##T##RegSizeInBytes);        \
542*f5c631daSSadaf Ebrahimi     Emit(OP##T##_z_zs | Rd(zdn) | ImmSVEPredicateConstraint(pattern) |    \
543*f5c631daSSadaf Ebrahimi          ImmUnsignedField<19, 16>(multiplier - 1));                       \
544*f5c631daSSadaf Ebrahimi   }
545*f5c631daSSadaf Ebrahimi VIXL_SVE_INC_DEC_VEC_LIST(VIXL_DEFINE_ASM_FUNC)
546*f5c631daSSadaf Ebrahimi #undef VIXL_DEFINE_ASM_FUNC
547*f5c631daSSadaf Ebrahimi 
548*f5c631daSSadaf Ebrahimi // SVEFPAccumulatingReduction.
549*f5c631daSSadaf Ebrahimi 
550*f5c631daSSadaf Ebrahimi void Assembler::fadda(const VRegister& vd,
551*f5c631daSSadaf Ebrahimi                       const PRegister& pg,
552*f5c631daSSadaf Ebrahimi                       const VRegister& vn,
553*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
554*f5c631daSSadaf Ebrahimi   // FADDA <V><dn>, <Pg>, <V><dn>, <Zm>.<T>
555*f5c631daSSadaf Ebrahimi   //  0110 0101 ..01 1000 001. .... .... ....
556*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 000 | Pg<12:10> | Zm<9:5> | Vdn<4:0>
557*f5c631daSSadaf Ebrahimi 
558*f5c631daSSadaf Ebrahimi   USE(vn);
559*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
560*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(vd.Is(vn));
561*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(vd.IsScalar());
562*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zm.GetLaneSizeInBytes() != kBRegSizeInBytes);
563*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zm, vd));
564*f5c631daSSadaf Ebrahimi 
565*f5c631daSSadaf Ebrahimi   Emit(FADDA_v_p_z | SVESize(zm) | Rd(vd) | PgLow8(pg) | Rn(zm));
566*f5c631daSSadaf Ebrahimi }
567*f5c631daSSadaf Ebrahimi 
568*f5c631daSSadaf Ebrahimi // SVEFPArithmetic_Predicated.
569*f5c631daSSadaf Ebrahimi 
fabd(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)570*f5c631daSSadaf Ebrahimi void Assembler::fabd(const ZRegister& zd,
571*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
572*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
573*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
574*f5c631daSSadaf Ebrahimi   // FABD <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
575*f5c631daSSadaf Ebrahimi   //  0110 0101 ..00 1000 100. .... .... ....
576*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<19:16> = 1000 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
577*f5c631daSSadaf Ebrahimi 
578*f5c631daSSadaf Ebrahimi   USE(zn);
579*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
580*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
581*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
582*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
583*f5c631daSSadaf Ebrahimi 
584*f5c631daSSadaf Ebrahimi   Emit(FABD_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
585*f5c631daSSadaf Ebrahimi }
586*f5c631daSSadaf Ebrahimi 
fadd(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,double imm)587*f5c631daSSadaf Ebrahimi void Assembler::fadd(const ZRegister& zd,
588*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
589*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
590*f5c631daSSadaf Ebrahimi                      double imm) {
591*f5c631daSSadaf Ebrahimi   // FADD <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <const>
592*f5c631daSSadaf Ebrahimi   //  0110 0101 ..01 1000 100. ..00 00.. ....
593*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 000 | Pg<12:10> | i1<5> | Zdn<4:0>
594*f5c631daSSadaf Ebrahimi 
595*f5c631daSSadaf Ebrahimi   USE(zn);
596*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
597*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
598*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
599*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
600*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((imm == 0.5) || (imm == 1.0));
601*f5c631daSSadaf Ebrahimi 
602*f5c631daSSadaf Ebrahimi   Instr i1 = (imm == 1.0) ? (1 << 5) : 0;
603*f5c631daSSadaf Ebrahimi   Emit(FADD_z_p_zs | SVESize(zd) | Rd(zd) | PgLow8(pg) | i1);
604*f5c631daSSadaf Ebrahimi }
605*f5c631daSSadaf Ebrahimi 
fadd(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)606*f5c631daSSadaf Ebrahimi void Assembler::fadd(const ZRegister& zd,
607*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
608*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
609*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
610*f5c631daSSadaf Ebrahimi   // FADD <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
611*f5c631daSSadaf Ebrahimi   //  0110 0101 ..00 0000 100. .... .... ....
612*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<19:16> = 0000 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
613*f5c631daSSadaf Ebrahimi 
614*f5c631daSSadaf Ebrahimi   USE(zn);
615*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
616*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
617*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
618*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
619*f5c631daSSadaf Ebrahimi 
620*f5c631daSSadaf Ebrahimi   Emit(FADD_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
621*f5c631daSSadaf Ebrahimi }
622*f5c631daSSadaf Ebrahimi 
fdiv(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)623*f5c631daSSadaf Ebrahimi void Assembler::fdiv(const ZRegister& zd,
624*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
625*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
626*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
627*f5c631daSSadaf Ebrahimi   // FDIV <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
628*f5c631daSSadaf Ebrahimi   //  0110 0101 ..00 1101 100. .... .... ....
629*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<19:16> = 1101 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
630*f5c631daSSadaf Ebrahimi 
631*f5c631daSSadaf Ebrahimi   USE(zn);
632*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
633*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
634*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
635*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
636*f5c631daSSadaf Ebrahimi 
637*f5c631daSSadaf Ebrahimi   Emit(FDIV_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
638*f5c631daSSadaf Ebrahimi }
639*f5c631daSSadaf Ebrahimi 
fdivr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)640*f5c631daSSadaf Ebrahimi void Assembler::fdivr(const ZRegister& zd,
641*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
642*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
643*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
644*f5c631daSSadaf Ebrahimi   // FDIVR <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
645*f5c631daSSadaf Ebrahimi   //  0110 0101 ..00 1100 100. .... .... ....
646*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<19:16> = 1100 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
647*f5c631daSSadaf Ebrahimi 
648*f5c631daSSadaf Ebrahimi   USE(zn);
649*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
650*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
651*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
652*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
653*f5c631daSSadaf Ebrahimi 
654*f5c631daSSadaf Ebrahimi   Emit(FDIVR_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
655*f5c631daSSadaf Ebrahimi }
656*f5c631daSSadaf Ebrahimi 
fmax(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,double imm)657*f5c631daSSadaf Ebrahimi void Assembler::fmax(const ZRegister& zd,
658*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
659*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
660*f5c631daSSadaf Ebrahimi                      double imm) {
661*f5c631daSSadaf Ebrahimi   // FMAX <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <const>
662*f5c631daSSadaf Ebrahimi   //  0110 0101 ..01 1110 100. ..00 00.. ....
663*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 110 | Pg<12:10> | i1<5> | Zdn<4:0>
664*f5c631daSSadaf Ebrahimi 
665*f5c631daSSadaf Ebrahimi   USE(zn);
666*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
667*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
668*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
669*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
670*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(((imm == 0.0) && (copysign(1.0, imm) == 1.0)) || (imm == 1.0));
671*f5c631daSSadaf Ebrahimi 
672*f5c631daSSadaf Ebrahimi   Instr i1 = (imm == 1.0) ? (1 << 5) : 0;
673*f5c631daSSadaf Ebrahimi   Emit(FMAX_z_p_zs | SVESize(zd) | Rd(zd) | PgLow8(pg) | i1);
674*f5c631daSSadaf Ebrahimi }
675*f5c631daSSadaf Ebrahimi 
fmax(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)676*f5c631daSSadaf Ebrahimi void Assembler::fmax(const ZRegister& zd,
677*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
678*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
679*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
680*f5c631daSSadaf Ebrahimi   // FMAX <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
681*f5c631daSSadaf Ebrahimi   //  0110 0101 ..00 0110 100. .... .... ....
682*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<19:16> = 0110 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
683*f5c631daSSadaf Ebrahimi 
684*f5c631daSSadaf Ebrahimi   USE(zn);
685*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
686*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
687*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
688*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
689*f5c631daSSadaf Ebrahimi 
690*f5c631daSSadaf Ebrahimi   Emit(FMAX_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
691*f5c631daSSadaf Ebrahimi }
692*f5c631daSSadaf Ebrahimi 
fmaxnm(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,double imm)693*f5c631daSSadaf Ebrahimi void Assembler::fmaxnm(const ZRegister& zd,
694*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
695*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
696*f5c631daSSadaf Ebrahimi                        double imm) {
697*f5c631daSSadaf Ebrahimi   // FMAXNM <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <const>
698*f5c631daSSadaf Ebrahimi   //  0110 0101 ..01 1100 100. ..00 00.. ....
699*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 100 | Pg<12:10> | i1<5> | Zdn<4:0>
700*f5c631daSSadaf Ebrahimi 
701*f5c631daSSadaf Ebrahimi   USE(zn);
702*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
703*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
704*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
705*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
706*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(((imm == 0.0) && (copysign(1.0, imm) == 1.0)) || (imm == 1.0));
707*f5c631daSSadaf Ebrahimi 
708*f5c631daSSadaf Ebrahimi   Instr i1 = (imm == 1.0) ? (1 << 5) : 0;
709*f5c631daSSadaf Ebrahimi   Emit(FMAXNM_z_p_zs | SVESize(zd) | Rd(zd) | PgLow8(pg) | i1);
710*f5c631daSSadaf Ebrahimi }
711*f5c631daSSadaf Ebrahimi 
fmaxnm(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)712*f5c631daSSadaf Ebrahimi void Assembler::fmaxnm(const ZRegister& zd,
713*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
714*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
715*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
716*f5c631daSSadaf Ebrahimi   // FMAXNM <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
717*f5c631daSSadaf Ebrahimi   //  0110 0101 ..00 0100 100. .... .... ....
718*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<19:16> = 0100 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
719*f5c631daSSadaf Ebrahimi 
720*f5c631daSSadaf Ebrahimi   USE(zn);
721*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
722*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
723*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
724*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
725*f5c631daSSadaf Ebrahimi 
726*f5c631daSSadaf Ebrahimi   Emit(FMAXNM_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
727*f5c631daSSadaf Ebrahimi }
728*f5c631daSSadaf Ebrahimi 
fmin(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,double imm)729*f5c631daSSadaf Ebrahimi void Assembler::fmin(const ZRegister& zd,
730*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
731*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
732*f5c631daSSadaf Ebrahimi                      double imm) {
733*f5c631daSSadaf Ebrahimi   // FMIN <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <const>
734*f5c631daSSadaf Ebrahimi   //  0110 0101 ..01 1111 100. ..00 00.. ....
735*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 111 | Pg<12:10> | i1<5> | Zdn<4:0>
736*f5c631daSSadaf Ebrahimi 
737*f5c631daSSadaf Ebrahimi   USE(zn);
738*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
739*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
740*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
741*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
742*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(((imm == 0.0) && (copysign(1.0, imm) == 1.0)) || (imm == 1.0));
743*f5c631daSSadaf Ebrahimi 
744*f5c631daSSadaf Ebrahimi   Instr i1 = (imm == 1.0) ? (1 << 5) : 0;
745*f5c631daSSadaf Ebrahimi   Emit(FMIN_z_p_zs | SVESize(zd) | Rd(zd) | PgLow8(pg) | i1);
746*f5c631daSSadaf Ebrahimi }
747*f5c631daSSadaf Ebrahimi 
fmin(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)748*f5c631daSSadaf Ebrahimi void Assembler::fmin(const ZRegister& zd,
749*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
750*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
751*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
752*f5c631daSSadaf Ebrahimi   // FMIN <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
753*f5c631daSSadaf Ebrahimi   //  0110 0101 ..00 0111 100. .... .... ....
754*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<19:16> = 0111 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
755*f5c631daSSadaf Ebrahimi 
756*f5c631daSSadaf Ebrahimi   USE(zn);
757*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
758*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
759*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
760*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
761*f5c631daSSadaf Ebrahimi 
762*f5c631daSSadaf Ebrahimi   Emit(FMIN_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
763*f5c631daSSadaf Ebrahimi }
764*f5c631daSSadaf Ebrahimi 
fminnm(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,double imm)765*f5c631daSSadaf Ebrahimi void Assembler::fminnm(const ZRegister& zd,
766*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
767*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
768*f5c631daSSadaf Ebrahimi                        double imm) {
769*f5c631daSSadaf Ebrahimi   // FMINNM <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <const>
770*f5c631daSSadaf Ebrahimi   //  0110 0101 ..01 1101 100. ..00 00.. ....
771*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 101 | Pg<12:10> | i1<5> | Zdn<4:0>
772*f5c631daSSadaf Ebrahimi 
773*f5c631daSSadaf Ebrahimi   USE(zn);
774*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
775*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
776*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
777*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
778*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(((imm == 0.0) && (copysign(1.0, imm) == 1.0)) || (imm == 1.0));
779*f5c631daSSadaf Ebrahimi 
780*f5c631daSSadaf Ebrahimi   Instr i1 = (imm == 1.0) ? (1 << 5) : 0;
781*f5c631daSSadaf Ebrahimi   Emit(FMINNM_z_p_zs | SVESize(zd) | Rd(zd) | PgLow8(pg) | i1);
782*f5c631daSSadaf Ebrahimi }
783*f5c631daSSadaf Ebrahimi 
fminnm(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)784*f5c631daSSadaf Ebrahimi void Assembler::fminnm(const ZRegister& zd,
785*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
786*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
787*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
788*f5c631daSSadaf Ebrahimi   // FMINNM <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
789*f5c631daSSadaf Ebrahimi   //  0110 0101 ..00 0101 100. .... .... ....
790*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<19:16> = 0101 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
791*f5c631daSSadaf Ebrahimi 
792*f5c631daSSadaf Ebrahimi   USE(zn);
793*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
794*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
795*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
796*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
797*f5c631daSSadaf Ebrahimi 
798*f5c631daSSadaf Ebrahimi   Emit(FMINNM_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
799*f5c631daSSadaf Ebrahimi }
800*f5c631daSSadaf Ebrahimi 
fmul(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,double imm)801*f5c631daSSadaf Ebrahimi void Assembler::fmul(const ZRegister& zd,
802*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
803*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
804*f5c631daSSadaf Ebrahimi                      double imm) {
805*f5c631daSSadaf Ebrahimi   // FMUL <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <const>
806*f5c631daSSadaf Ebrahimi   //  0110 0101 ..01 1010 100. ..00 00.. ....
807*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 010 | Pg<12:10> | i1<5> | Zdn<4:0>
808*f5c631daSSadaf Ebrahimi 
809*f5c631daSSadaf Ebrahimi   USE(zn);
810*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
811*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
812*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
813*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
814*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((imm == 0.5) || (imm == 2.0));
815*f5c631daSSadaf Ebrahimi 
816*f5c631daSSadaf Ebrahimi   Instr i1 = (imm == 2.0) ? (1 << 5) : 0;
817*f5c631daSSadaf Ebrahimi   Emit(FMUL_z_p_zs | SVESize(zd) | Rd(zd) | PgLow8(pg) | i1);
818*f5c631daSSadaf Ebrahimi }
819*f5c631daSSadaf Ebrahimi 
fmul(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)820*f5c631daSSadaf Ebrahimi void Assembler::fmul(const ZRegister& zd,
821*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
822*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
823*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
824*f5c631daSSadaf Ebrahimi   // FMUL <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
825*f5c631daSSadaf Ebrahimi   //  0110 0101 ..00 0010 100. .... .... ....
826*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<19:16> = 0010 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
827*f5c631daSSadaf Ebrahimi 
828*f5c631daSSadaf Ebrahimi   USE(zn);
829*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
830*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
831*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
832*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
833*f5c631daSSadaf Ebrahimi 
834*f5c631daSSadaf Ebrahimi   Emit(FMUL_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
835*f5c631daSSadaf Ebrahimi }
836*f5c631daSSadaf Ebrahimi 
fmulx(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)837*f5c631daSSadaf Ebrahimi void Assembler::fmulx(const ZRegister& zd,
838*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
839*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
840*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
841*f5c631daSSadaf Ebrahimi   // FMULX <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
842*f5c631daSSadaf Ebrahimi   //  0110 0101 ..00 1010 100. .... .... ....
843*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<19:16> = 1010 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
844*f5c631daSSadaf Ebrahimi 
845*f5c631daSSadaf Ebrahimi   USE(zn);
846*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
847*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
848*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
849*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
850*f5c631daSSadaf Ebrahimi 
851*f5c631daSSadaf Ebrahimi   Emit(FMULX_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
852*f5c631daSSadaf Ebrahimi }
853*f5c631daSSadaf Ebrahimi 
fscale(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)854*f5c631daSSadaf Ebrahimi void Assembler::fscale(const ZRegister& zd,
855*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
856*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
857*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
858*f5c631daSSadaf Ebrahimi   // FSCALE <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
859*f5c631daSSadaf Ebrahimi   //  0110 0101 ..00 1001 100. .... .... ....
860*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<19:16> = 1001 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
861*f5c631daSSadaf Ebrahimi 
862*f5c631daSSadaf Ebrahimi   USE(zn);
863*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
864*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
865*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
866*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
867*f5c631daSSadaf Ebrahimi 
868*f5c631daSSadaf Ebrahimi   Emit(FSCALE_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
869*f5c631daSSadaf Ebrahimi }
870*f5c631daSSadaf Ebrahimi 
fsub(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,double imm)871*f5c631daSSadaf Ebrahimi void Assembler::fsub(const ZRegister& zd,
872*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
873*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
874*f5c631daSSadaf Ebrahimi                      double imm) {
875*f5c631daSSadaf Ebrahimi   // FSUB <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <const>
876*f5c631daSSadaf Ebrahimi   //  0110 0101 ..01 1001 100. ..00 00.. ....
877*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 001 | Pg<12:10> | i1<5> | Zdn<4:0>
878*f5c631daSSadaf Ebrahimi 
879*f5c631daSSadaf Ebrahimi   USE(zn);
880*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
881*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
882*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
883*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
884*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((imm == 0.5) || (imm == 1.0));
885*f5c631daSSadaf Ebrahimi 
886*f5c631daSSadaf Ebrahimi   Instr i1 = (imm == 1.0) ? (1 << 5) : 0;
887*f5c631daSSadaf Ebrahimi   Emit(FSUB_z_p_zs | SVESize(zd) | Rd(zd) | PgLow8(pg) | i1);
888*f5c631daSSadaf Ebrahimi }
889*f5c631daSSadaf Ebrahimi 
fsub(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)890*f5c631daSSadaf Ebrahimi void Assembler::fsub(const ZRegister& zd,
891*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
892*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
893*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
894*f5c631daSSadaf Ebrahimi   // FSUB <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
895*f5c631daSSadaf Ebrahimi   //  0110 0101 ..00 0001 100. .... .... ....
896*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<19:16> = 0001 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
897*f5c631daSSadaf Ebrahimi 
898*f5c631daSSadaf Ebrahimi   USE(zn);
899*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
900*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
901*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
902*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
903*f5c631daSSadaf Ebrahimi 
904*f5c631daSSadaf Ebrahimi   Emit(FSUB_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
905*f5c631daSSadaf Ebrahimi }
906*f5c631daSSadaf Ebrahimi 
fsubr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,double imm)907*f5c631daSSadaf Ebrahimi void Assembler::fsubr(const ZRegister& zd,
908*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
909*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
910*f5c631daSSadaf Ebrahimi                       double imm) {
911*f5c631daSSadaf Ebrahimi   // FSUBR <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <const>
912*f5c631daSSadaf Ebrahimi   //  0110 0101 ..01 1011 100. ..00 00.. ....
913*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 011 | Pg<12:10> | i1<5> | Zdn<4:0>
914*f5c631daSSadaf Ebrahimi 
915*f5c631daSSadaf Ebrahimi   USE(zn);
916*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
917*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
918*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
919*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
920*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((imm == 0.5) || (imm == 1.0));
921*f5c631daSSadaf Ebrahimi 
922*f5c631daSSadaf Ebrahimi   Instr i1 = (imm == 1.0) ? (1 << 5) : 0;
923*f5c631daSSadaf Ebrahimi   Emit(FSUBR_z_p_zs | SVESize(zd) | Rd(zd) | PgLow8(pg) | i1);
924*f5c631daSSadaf Ebrahimi }
925*f5c631daSSadaf Ebrahimi 
fsubr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)926*f5c631daSSadaf Ebrahimi void Assembler::fsubr(const ZRegister& zd,
927*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
928*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
929*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
930*f5c631daSSadaf Ebrahimi   // FSUBR <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
931*f5c631daSSadaf Ebrahimi   //  0110 0101 ..00 0011 100. .... .... ....
932*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<19:16> = 0011 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
933*f5c631daSSadaf Ebrahimi 
934*f5c631daSSadaf Ebrahimi   USE(zn);
935*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
936*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
937*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
938*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
939*f5c631daSSadaf Ebrahimi 
940*f5c631daSSadaf Ebrahimi   Emit(FSUBR_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
941*f5c631daSSadaf Ebrahimi }
942*f5c631daSSadaf Ebrahimi 
ftmad(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm,int imm3)943*f5c631daSSadaf Ebrahimi void Assembler::ftmad(const ZRegister& zd,
944*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
945*f5c631daSSadaf Ebrahimi                       const ZRegister& zm,
946*f5c631daSSadaf Ebrahimi                       int imm3) {
947*f5c631daSSadaf Ebrahimi   // FTMAD <Zdn>.<T>, <Zdn>.<T>, <Zm>.<T>, #<imm>
948*f5c631daSSadaf Ebrahimi   //  0110 0101 ..01 0... 1000 00.. .... ....
949*f5c631daSSadaf Ebrahimi   //  size<23:22> | imm3<18:16> | Zm<9:5> | Zdn<4:0>
950*f5c631daSSadaf Ebrahimi 
951*f5c631daSSadaf Ebrahimi   USE(zn);
952*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
953*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
954*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
955*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
956*f5c631daSSadaf Ebrahimi 
957*f5c631daSSadaf Ebrahimi   Emit(FTMAD_z_zzi | SVESize(zd) | Rd(zd) | Rn(zm) |
958*f5c631daSSadaf Ebrahimi        ImmUnsignedField<18, 16>(imm3));
959*f5c631daSSadaf Ebrahimi }
960*f5c631daSSadaf Ebrahimi 
961*f5c631daSSadaf Ebrahimi // SVEFPArithmeticUnpredicated.
962*f5c631daSSadaf Ebrahimi 
fadd(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)963*f5c631daSSadaf Ebrahimi void Assembler::fadd(const ZRegister& zd,
964*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
965*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
966*f5c631daSSadaf Ebrahimi   // FADD <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
967*f5c631daSSadaf Ebrahimi   //  0110 0101 ..0. .... 0000 00.. .... ....
968*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<12:10> = 000 | Zn<9:5> | Zd<4:0>
969*f5c631daSSadaf Ebrahimi 
970*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
971*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
972*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
973*f5c631daSSadaf Ebrahimi 
974*f5c631daSSadaf Ebrahimi   Emit(FADD_z_zz | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
975*f5c631daSSadaf Ebrahimi }
976*f5c631daSSadaf Ebrahimi 
fmul(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)977*f5c631daSSadaf Ebrahimi void Assembler::fmul(const ZRegister& zd,
978*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
979*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
980*f5c631daSSadaf Ebrahimi   // FMUL <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
981*f5c631daSSadaf Ebrahimi   //  0110 0101 ..0. .... 0000 10.. .... ....
982*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<12:10> = 010 | Zn<9:5> | Zd<4:0>
983*f5c631daSSadaf Ebrahimi 
984*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
985*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
986*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
987*f5c631daSSadaf Ebrahimi 
988*f5c631daSSadaf Ebrahimi   Emit(FMUL_z_zz | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
989*f5c631daSSadaf Ebrahimi }
990*f5c631daSSadaf Ebrahimi 
frecps(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)991*f5c631daSSadaf Ebrahimi void Assembler::frecps(const ZRegister& zd,
992*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
993*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
994*f5c631daSSadaf Ebrahimi   // FRECPS <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
995*f5c631daSSadaf Ebrahimi   //  0110 0101 ..0. .... 0001 10.. .... ....
996*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<12:10> = 110 | Zn<9:5> | Zd<4:0>
997*f5c631daSSadaf Ebrahimi 
998*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
999*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
1000*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
1001*f5c631daSSadaf Ebrahimi 
1002*f5c631daSSadaf Ebrahimi   Emit(FRECPS_z_zz | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
1003*f5c631daSSadaf Ebrahimi }
1004*f5c631daSSadaf Ebrahimi 
frsqrts(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)1005*f5c631daSSadaf Ebrahimi void Assembler::frsqrts(const ZRegister& zd,
1006*f5c631daSSadaf Ebrahimi                         const ZRegister& zn,
1007*f5c631daSSadaf Ebrahimi                         const ZRegister& zm) {
1008*f5c631daSSadaf Ebrahimi   // FRSQRTS <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
1009*f5c631daSSadaf Ebrahimi   //  0110 0101 ..0. .... 0001 11.. .... ....
1010*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<12:10> = 111 | Zn<9:5> | Zd<4:0>
1011*f5c631daSSadaf Ebrahimi 
1012*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1013*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
1014*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
1015*f5c631daSSadaf Ebrahimi 
1016*f5c631daSSadaf Ebrahimi   Emit(FRSQRTS_z_zz | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
1017*f5c631daSSadaf Ebrahimi }
1018*f5c631daSSadaf Ebrahimi 
fsub(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)1019*f5c631daSSadaf Ebrahimi void Assembler::fsub(const ZRegister& zd,
1020*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
1021*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
1022*f5c631daSSadaf Ebrahimi   // FSUB <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
1023*f5c631daSSadaf Ebrahimi   //  0110 0101 ..0. .... 0000 01.. .... ....
1024*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<12:10> = 001 | Zn<9:5> | Zd<4:0>
1025*f5c631daSSadaf Ebrahimi 
1026*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1027*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
1028*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
1029*f5c631daSSadaf Ebrahimi 
1030*f5c631daSSadaf Ebrahimi   Emit(FSUB_z_zz | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
1031*f5c631daSSadaf Ebrahimi }
1032*f5c631daSSadaf Ebrahimi 
ftsmul(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)1033*f5c631daSSadaf Ebrahimi void Assembler::ftsmul(const ZRegister& zd,
1034*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
1035*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
1036*f5c631daSSadaf Ebrahimi   // FTSMUL <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
1037*f5c631daSSadaf Ebrahimi   //  0110 0101 ..0. .... 0000 11.. .... ....
1038*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<12:10> = 011 | Zn<9:5> | Zd<4:0>
1039*f5c631daSSadaf Ebrahimi 
1040*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1041*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
1042*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
1043*f5c631daSSadaf Ebrahimi 
1044*f5c631daSSadaf Ebrahimi   Emit(FTSMUL_z_zz | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
1045*f5c631daSSadaf Ebrahimi }
1046*f5c631daSSadaf Ebrahimi 
1047*f5c631daSSadaf Ebrahimi // SVEFPCompareVectors.
1048*f5c631daSSadaf Ebrahimi 
facge(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)1049*f5c631daSSadaf Ebrahimi void Assembler::facge(const PRegisterWithLaneSize& pd,
1050*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
1051*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
1052*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
1053*f5c631daSSadaf Ebrahimi   // FACGE <Pd>.<T>, <Pg>/Z, <Zn>.<T>, <Zm>.<T>
1054*f5c631daSSadaf Ebrahimi   //  0110 0101 ..0. .... 110. .... ...1 ....
1055*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<15> = 1 | o2<13> = 0 | Pg<12:10> | Zn<9:5> |
1056*f5c631daSSadaf Ebrahimi   //  o3<4> = 1 | Pd<3:0>
1057*f5c631daSSadaf Ebrahimi 
1058*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1059*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
1060*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() != kBRegSizeInBytes);
1061*f5c631daSSadaf Ebrahimi 
1062*f5c631daSSadaf Ebrahimi   Emit(FACGE_p_p_zz | SVESize(zn) | Pd(pd) | PgLow8(pg) | Rn(zn) | Rm(zm));
1063*f5c631daSSadaf Ebrahimi }
1064*f5c631daSSadaf Ebrahimi 
facgt(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)1065*f5c631daSSadaf Ebrahimi void Assembler::facgt(const PRegisterWithLaneSize& pd,
1066*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
1067*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
1068*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
1069*f5c631daSSadaf Ebrahimi   // FACGT <Pd>.<T>, <Pg>/Z, <Zn>.<T>, <Zm>.<T>
1070*f5c631daSSadaf Ebrahimi   //  0110 0101 ..0. .... 111. .... ...1 ....
1071*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<15> = 1 | o2<13> = 1 | Pg<12:10> | Zn<9:5> |
1072*f5c631daSSadaf Ebrahimi   //  o3<4> = 1 | Pd<3:0>
1073*f5c631daSSadaf Ebrahimi 
1074*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1075*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
1076*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() != kBRegSizeInBytes);
1077*f5c631daSSadaf Ebrahimi 
1078*f5c631daSSadaf Ebrahimi   Emit(FACGT_p_p_zz | SVESize(zn) | Pd(pd) | PgLow8(pg) | Rn(zn) | Rm(zm));
1079*f5c631daSSadaf Ebrahimi }
1080*f5c631daSSadaf Ebrahimi 
fcmeq(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)1081*f5c631daSSadaf Ebrahimi void Assembler::fcmeq(const PRegisterWithLaneSize& pd,
1082*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
1083*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
1084*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
1085*f5c631daSSadaf Ebrahimi   // FCMEQ <Pd>.<T>, <Pg>/Z, <Zn>.<T>, <Zm>.<T>
1086*f5c631daSSadaf Ebrahimi   //  0110 0101 ..0. .... 011. .... ...0 ....
1087*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<15> = 0 | o2<13> = 1 | Pg<12:10> | Zn<9:5> |
1088*f5c631daSSadaf Ebrahimi   //  o3<4> = 0 | Pd<3:0>
1089*f5c631daSSadaf Ebrahimi 
1090*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1091*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
1092*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() != kBRegSizeInBytes);
1093*f5c631daSSadaf Ebrahimi 
1094*f5c631daSSadaf Ebrahimi   Emit(FCMEQ_p_p_zz | SVESize(zn) | Pd(pd) | PgLow8(pg) | Rn(zn) | Rm(zm));
1095*f5c631daSSadaf Ebrahimi }
1096*f5c631daSSadaf Ebrahimi 
fcmge(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)1097*f5c631daSSadaf Ebrahimi void Assembler::fcmge(const PRegisterWithLaneSize& pd,
1098*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
1099*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
1100*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
1101*f5c631daSSadaf Ebrahimi   // FCMGE <Pd>.<T>, <Pg>/Z, <Zn>.<T>, <Zm>.<T>
1102*f5c631daSSadaf Ebrahimi   //  0110 0101 ..0. .... 010. .... ...0 ....
1103*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<15> = 0 | o2<13> = 0 | Pg<12:10> | Zn<9:5> |
1104*f5c631daSSadaf Ebrahimi   //  o3<4> = 0 | Pd<3:0>
1105*f5c631daSSadaf Ebrahimi 
1106*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1107*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
1108*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() != kBRegSizeInBytes);
1109*f5c631daSSadaf Ebrahimi 
1110*f5c631daSSadaf Ebrahimi   Emit(FCMGE_p_p_zz | SVESize(zn) | Pd(pd) | PgLow8(pg) | Rn(zn) | Rm(zm));
1111*f5c631daSSadaf Ebrahimi }
1112*f5c631daSSadaf Ebrahimi 
fcmgt(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)1113*f5c631daSSadaf Ebrahimi void Assembler::fcmgt(const PRegisterWithLaneSize& pd,
1114*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
1115*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
1116*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
1117*f5c631daSSadaf Ebrahimi   // FCMGT <Pd>.<T>, <Pg>/Z, <Zn>.<T>, <Zm>.<T>
1118*f5c631daSSadaf Ebrahimi   //  0110 0101 ..0. .... 010. .... ...1 ....
1119*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<15> = 0 | o2<13> = 0 | Pg<12:10> | Zn<9:5> |
1120*f5c631daSSadaf Ebrahimi   //  o3<4> = 1 | Pd<3:0>
1121*f5c631daSSadaf Ebrahimi 
1122*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1123*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
1124*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() != kBRegSizeInBytes);
1125*f5c631daSSadaf Ebrahimi 
1126*f5c631daSSadaf Ebrahimi   Emit(FCMGT_p_p_zz | SVESize(zn) | Pd(pd) | PgLow8(pg) | Rn(zn) | Rm(zm));
1127*f5c631daSSadaf Ebrahimi }
1128*f5c631daSSadaf Ebrahimi 
fcmne(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)1129*f5c631daSSadaf Ebrahimi void Assembler::fcmne(const PRegisterWithLaneSize& pd,
1130*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
1131*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
1132*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
1133*f5c631daSSadaf Ebrahimi   // FCMNE <Pd>.<T>, <Pg>/Z, <Zn>.<T>, <Zm>.<T>
1134*f5c631daSSadaf Ebrahimi   //  0110 0101 ..0. .... 011. .... ...1 ....
1135*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<15> = 0 | o2<13> = 1 | Pg<12:10> | Zn<9:5> |
1136*f5c631daSSadaf Ebrahimi   //  o3<4> = 1 | Pd<3:0>
1137*f5c631daSSadaf Ebrahimi 
1138*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1139*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
1140*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() != kBRegSizeInBytes);
1141*f5c631daSSadaf Ebrahimi 
1142*f5c631daSSadaf Ebrahimi   Emit(FCMNE_p_p_zz | SVESize(zn) | Pd(pd) | PgLow8(pg) | Rn(zn) | Rm(zm));
1143*f5c631daSSadaf Ebrahimi }
1144*f5c631daSSadaf Ebrahimi 
fcmuo(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)1145*f5c631daSSadaf Ebrahimi void Assembler::fcmuo(const PRegisterWithLaneSize& pd,
1146*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
1147*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
1148*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
1149*f5c631daSSadaf Ebrahimi   // FCMUO <Pd>.<T>, <Pg>/Z, <Zn>.<T>, <Zm>.<T>
1150*f5c631daSSadaf Ebrahimi   //  0110 0101 ..0. .... 110. .... ...0 ....
1151*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<15> = 1 | o2<13> = 0 | Pg<12:10> | Zn<9:5> |
1152*f5c631daSSadaf Ebrahimi   //  o3<4> = 0 | Pd<3:0>
1153*f5c631daSSadaf Ebrahimi 
1154*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1155*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
1156*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() != kBRegSizeInBytes);
1157*f5c631daSSadaf Ebrahimi 
1158*f5c631daSSadaf Ebrahimi   Emit(FCMUO_p_p_zz | SVESize(zn) | Pd(pd) | PgLow8(pg) | Rn(zn) | Rm(zm));
1159*f5c631daSSadaf Ebrahimi }
1160*f5c631daSSadaf Ebrahimi 
1161*f5c631daSSadaf Ebrahimi // SVEFPCompareWithZero.
1162*f5c631daSSadaf Ebrahimi 
fcmeq(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,double zero)1163*f5c631daSSadaf Ebrahimi void Assembler::fcmeq(const PRegisterWithLaneSize& pd,
1164*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
1165*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
1166*f5c631daSSadaf Ebrahimi                       double zero) {
1167*f5c631daSSadaf Ebrahimi   // FCMEQ <Pd>.<T>, <Pg>/Z, <Zn>.<T>, #0.0
1168*f5c631daSSadaf Ebrahimi   //  0110 0101 ..01 0010 001. .... ...0 ....
1169*f5c631daSSadaf Ebrahimi   //  size<23:22> | eq<17> = 1 | lt<16> = 0 | Pg<12:10> | Zn<9:5> | ne<4> = 0 |
1170*f5c631daSSadaf Ebrahimi   //  Pd<3:0>
1171*f5c631daSSadaf Ebrahimi 
1172*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1173*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() != kBRegSizeInBytes);
1174*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zero == 0.0);
1175*f5c631daSSadaf Ebrahimi   USE(zero);
1176*f5c631daSSadaf Ebrahimi 
1177*f5c631daSSadaf Ebrahimi   Emit(FCMEQ_p_p_z0 | SVESize(zn) | Pd(pd) | PgLow8(pg) | Rn(zn));
1178*f5c631daSSadaf Ebrahimi }
1179*f5c631daSSadaf Ebrahimi 
fcmge(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,double zero)1180*f5c631daSSadaf Ebrahimi void Assembler::fcmge(const PRegisterWithLaneSize& pd,
1181*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
1182*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
1183*f5c631daSSadaf Ebrahimi                       double zero) {
1184*f5c631daSSadaf Ebrahimi   // FCMGE <Pd>.<T>, <Pg>/Z, <Zn>.<T>, #0.0
1185*f5c631daSSadaf Ebrahimi   //  0110 0101 ..01 0000 001. .... ...0 ....
1186*f5c631daSSadaf Ebrahimi   //  size<23:22> | eq<17> = 0 | lt<16> = 0 | Pg<12:10> | Zn<9:5> | ne<4> = 0 |
1187*f5c631daSSadaf Ebrahimi   //  Pd<3:0>
1188*f5c631daSSadaf Ebrahimi 
1189*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1190*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() != kBRegSizeInBytes);
1191*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zero == 0.0);
1192*f5c631daSSadaf Ebrahimi   USE(zero);
1193*f5c631daSSadaf Ebrahimi 
1194*f5c631daSSadaf Ebrahimi   Emit(FCMGE_p_p_z0 | SVESize(zn) | Pd(pd) | PgLow8(pg) | Rn(zn));
1195*f5c631daSSadaf Ebrahimi }
1196*f5c631daSSadaf Ebrahimi 
fcmgt(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,double zero)1197*f5c631daSSadaf Ebrahimi void Assembler::fcmgt(const PRegisterWithLaneSize& pd,
1198*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
1199*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
1200*f5c631daSSadaf Ebrahimi                       double zero) {
1201*f5c631daSSadaf Ebrahimi   // FCMGT <Pd>.<T>, <Pg>/Z, <Zn>.<T>, #0.0
1202*f5c631daSSadaf Ebrahimi   //  0110 0101 ..01 0000 001. .... ...1 ....
1203*f5c631daSSadaf Ebrahimi   //  size<23:22> | eq<17> = 0 | lt<16> = 0 | Pg<12:10> | Zn<9:5> | ne<4> = 1 |
1204*f5c631daSSadaf Ebrahimi   //  Pd<3:0>
1205*f5c631daSSadaf Ebrahimi 
1206*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1207*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() != kBRegSizeInBytes);
1208*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zero == 0.0);
1209*f5c631daSSadaf Ebrahimi   USE(zero);
1210*f5c631daSSadaf Ebrahimi 
1211*f5c631daSSadaf Ebrahimi   Emit(FCMGT_p_p_z0 | SVESize(zn) | Pd(pd) | PgLow8(pg) | Rn(zn));
1212*f5c631daSSadaf Ebrahimi }
1213*f5c631daSSadaf Ebrahimi 
fcmle(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,double zero)1214*f5c631daSSadaf Ebrahimi void Assembler::fcmle(const PRegisterWithLaneSize& pd,
1215*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
1216*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
1217*f5c631daSSadaf Ebrahimi                       double zero) {
1218*f5c631daSSadaf Ebrahimi   // FCMLE <Pd>.<T>, <Pg>/Z, <Zn>.<T>, #0.0
1219*f5c631daSSadaf Ebrahimi   //  0110 0101 ..01 0001 001. .... ...1 ....
1220*f5c631daSSadaf Ebrahimi   //  size<23:22> | eq<17> = 0 | lt<16> = 1 | Pg<12:10> | Zn<9:5> | ne<4> = 1 |
1221*f5c631daSSadaf Ebrahimi   //  Pd<3:0>
1222*f5c631daSSadaf Ebrahimi 
1223*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1224*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() != kBRegSizeInBytes);
1225*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zero == 0.0);
1226*f5c631daSSadaf Ebrahimi   USE(zero);
1227*f5c631daSSadaf Ebrahimi 
1228*f5c631daSSadaf Ebrahimi   Emit(FCMLE_p_p_z0 | SVESize(zn) | Pd(pd) | PgLow8(pg) | Rn(zn));
1229*f5c631daSSadaf Ebrahimi }
1230*f5c631daSSadaf Ebrahimi 
fcmlt(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,double zero)1231*f5c631daSSadaf Ebrahimi void Assembler::fcmlt(const PRegisterWithLaneSize& pd,
1232*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
1233*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
1234*f5c631daSSadaf Ebrahimi                       double zero) {
1235*f5c631daSSadaf Ebrahimi   // FCMLT <Pd>.<T>, <Pg>/Z, <Zn>.<T>, #0.0
1236*f5c631daSSadaf Ebrahimi   //  0110 0101 ..01 0001 001. .... ...0 ....
1237*f5c631daSSadaf Ebrahimi   //  size<23:22> | eq<17> = 0 | lt<16> = 1 | Pg<12:10> | Zn<9:5> | ne<4> = 0 |
1238*f5c631daSSadaf Ebrahimi   //  Pd<3:0>
1239*f5c631daSSadaf Ebrahimi 
1240*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1241*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() != kBRegSizeInBytes);
1242*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zero == 0.0);
1243*f5c631daSSadaf Ebrahimi   USE(zero);
1244*f5c631daSSadaf Ebrahimi 
1245*f5c631daSSadaf Ebrahimi   Emit(FCMLT_p_p_z0 | SVESize(zn) | Pd(pd) | PgLow8(pg) | Rn(zn));
1246*f5c631daSSadaf Ebrahimi }
1247*f5c631daSSadaf Ebrahimi 
fcmne(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,double zero)1248*f5c631daSSadaf Ebrahimi void Assembler::fcmne(const PRegisterWithLaneSize& pd,
1249*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
1250*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
1251*f5c631daSSadaf Ebrahimi                       double zero) {
1252*f5c631daSSadaf Ebrahimi   // FCMNE <Pd>.<T>, <Pg>/Z, <Zn>.<T>, #0.0
1253*f5c631daSSadaf Ebrahimi   //  0110 0101 ..01 0011 001. .... ...0 ....
1254*f5c631daSSadaf Ebrahimi   //  size<23:22> | eq<17> = 1 | lt<16> = 1 | Pg<12:10> | Zn<9:5> | ne<4> = 0 |
1255*f5c631daSSadaf Ebrahimi   //  Pd<3:0>
1256*f5c631daSSadaf Ebrahimi 
1257*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1258*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() != kBRegSizeInBytes);
1259*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zero == 0.0);
1260*f5c631daSSadaf Ebrahimi   USE(zero);
1261*f5c631daSSadaf Ebrahimi 
1262*f5c631daSSadaf Ebrahimi   Emit(FCMNE_p_p_z0 | SVESize(zn) | Pd(pd) | PgLow8(pg) | Rn(zn));
1263*f5c631daSSadaf Ebrahimi }
1264*f5c631daSSadaf Ebrahimi 
1265*f5c631daSSadaf Ebrahimi // SVEFPComplexAddition.
1266*f5c631daSSadaf Ebrahimi 
fcadd(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm,int rot)1267*f5c631daSSadaf Ebrahimi void Assembler::fcadd(const ZRegister& zd,
1268*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
1269*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
1270*f5c631daSSadaf Ebrahimi                       const ZRegister& zm,
1271*f5c631daSSadaf Ebrahimi                       int rot) {
1272*f5c631daSSadaf Ebrahimi   // FCADD <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>, <const>
1273*f5c631daSSadaf Ebrahimi   //  0110 0100 ..00 000. 100. .... .... ....
1274*f5c631daSSadaf Ebrahimi   //  size<23:22> | rot<16> | Pg<12:10> | Zm<9:5> | Zdn<4:0>
1275*f5c631daSSadaf Ebrahimi 
1276*f5c631daSSadaf Ebrahimi   USE(zn);
1277*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1278*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
1279*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
1280*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
1281*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((rot == 90) || (rot == 270));
1282*f5c631daSSadaf Ebrahimi 
1283*f5c631daSSadaf Ebrahimi   Instr rotate_bit = (rot == 90) ? 0 : (1 << 16);
1284*f5c631daSSadaf Ebrahimi   Emit(FCADD_z_p_zz | rotate_bit | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
1285*f5c631daSSadaf Ebrahimi }
1286*f5c631daSSadaf Ebrahimi 
1287*f5c631daSSadaf Ebrahimi // SVEFPComplexMulAdd.
1288*f5c631daSSadaf Ebrahimi 
fcmla(const ZRegister & zda,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm,int rot)1289*f5c631daSSadaf Ebrahimi void Assembler::fcmla(const ZRegister& zda,
1290*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
1291*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
1292*f5c631daSSadaf Ebrahimi                       const ZRegister& zm,
1293*f5c631daSSadaf Ebrahimi                       int rot) {
1294*f5c631daSSadaf Ebrahimi   // FCMLA <Zda>.<T>, <Pg>/M, <Zn>.<T>, <Zm>.<T>, <const>
1295*f5c631daSSadaf Ebrahimi   //  0110 0100 ..0. .... 0... .... .... ....
1296*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | rot<14:13> | Pg<12:10> | Zn<9:5> | Zda<4:0>
1297*f5c631daSSadaf Ebrahimi 
1298*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1299*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn, zm));
1300*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() != kBRegSizeInBytes);
1301*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((rot == 0) || (rot == 90) || (rot == 180) || (rot == 270));
1302*f5c631daSSadaf Ebrahimi 
1303*f5c631daSSadaf Ebrahimi   Instr rotate_bit = (rot / 90) << 13;
1304*f5c631daSSadaf Ebrahimi   Emit(FCMLA_z_p_zzz | rotate_bit | SVESize(zda) | Rd(zda) | PgLow8(pg) |
1305*f5c631daSSadaf Ebrahimi        Rn(zn) | Rm(zm));
1306*f5c631daSSadaf Ebrahimi }
1307*f5c631daSSadaf Ebrahimi 
1308*f5c631daSSadaf Ebrahimi // SVEFPComplexMulAddIndex.
1309*f5c631daSSadaf Ebrahimi 
fcmla(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm,int index,int rot)1310*f5c631daSSadaf Ebrahimi void Assembler::fcmla(const ZRegister& zda,
1311*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
1312*f5c631daSSadaf Ebrahimi                       const ZRegister& zm,
1313*f5c631daSSadaf Ebrahimi                       int index,
1314*f5c631daSSadaf Ebrahimi                       int rot) {
1315*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1316*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn, zm));
1317*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((rot == 0) || (rot == 90) || (rot == 180) || (rot == 270));
1318*f5c631daSSadaf Ebrahimi 
1319*f5c631daSSadaf Ebrahimi   Instr rotate_bit = (rot / 90) << 10;
1320*f5c631daSSadaf Ebrahimi   Emit(FCMLA_z_zzzi_h | SVEMulComplexIndexHelper(zm, index) | rotate_bit |
1321*f5c631daSSadaf Ebrahimi        Rd(zda) | Rn(zn));
1322*f5c631daSSadaf Ebrahimi }
1323*f5c631daSSadaf Ebrahimi 
1324*f5c631daSSadaf Ebrahimi // SVEFPFastReduction.
1325*f5c631daSSadaf Ebrahimi 
faddv(const VRegister & vd,const PRegister & pg,const ZRegister & zn)1326*f5c631daSSadaf Ebrahimi void Assembler::faddv(const VRegister& vd,
1327*f5c631daSSadaf Ebrahimi                       const PRegister& pg,
1328*f5c631daSSadaf Ebrahimi                       const ZRegister& zn) {
1329*f5c631daSSadaf Ebrahimi   // FADDV <V><d>, <Pg>, <Zn>.<T>
1330*f5c631daSSadaf Ebrahimi   //  0110 0101 ..00 0000 001. .... .... ....
1331*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 000 | Pg<12:10> | Zn<9:5> | Vd<4:0>
1332*f5c631daSSadaf Ebrahimi 
1333*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1334*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(vd.IsScalar());
1335*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() != kBRegSizeInBytes);
1336*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, vd));
1337*f5c631daSSadaf Ebrahimi 
1338*f5c631daSSadaf Ebrahimi   Emit(FADDV_v_p_z | SVESize(zn) | Rd(vd) | PgLow8(pg) | Rn(zn));
1339*f5c631daSSadaf Ebrahimi }
1340*f5c631daSSadaf Ebrahimi 
fmaxnmv(const VRegister & vd,const PRegister & pg,const ZRegister & zn)1341*f5c631daSSadaf Ebrahimi void Assembler::fmaxnmv(const VRegister& vd,
1342*f5c631daSSadaf Ebrahimi                         const PRegister& pg,
1343*f5c631daSSadaf Ebrahimi                         const ZRegister& zn) {
1344*f5c631daSSadaf Ebrahimi   // FMAXNMV <V><d>, <Pg>, <Zn>.<T>
1345*f5c631daSSadaf Ebrahimi   //  0110 0101 ..00 0100 001. .... .... ....
1346*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 100 | Pg<12:10> | Zn<9:5> | Vd<4:0>
1347*f5c631daSSadaf Ebrahimi 
1348*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1349*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(vd.IsScalar());
1350*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() != kBRegSizeInBytes);
1351*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, vd));
1352*f5c631daSSadaf Ebrahimi 
1353*f5c631daSSadaf Ebrahimi   Emit(FMAXNMV_v_p_z | SVESize(zn) | Rd(vd) | PgLow8(pg) | Rn(zn));
1354*f5c631daSSadaf Ebrahimi }
1355*f5c631daSSadaf Ebrahimi 
fmaxv(const VRegister & vd,const PRegister & pg,const ZRegister & zn)1356*f5c631daSSadaf Ebrahimi void Assembler::fmaxv(const VRegister& vd,
1357*f5c631daSSadaf Ebrahimi                       const PRegister& pg,
1358*f5c631daSSadaf Ebrahimi                       const ZRegister& zn) {
1359*f5c631daSSadaf Ebrahimi   // FMAXV <V><d>, <Pg>, <Zn>.<T>
1360*f5c631daSSadaf Ebrahimi   //  0110 0101 ..00 0110 001. .... .... ....
1361*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 110 | Pg<12:10> | Zn<9:5> | Vd<4:0>
1362*f5c631daSSadaf Ebrahimi 
1363*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1364*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(vd.IsScalar());
1365*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() != kBRegSizeInBytes);
1366*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, vd));
1367*f5c631daSSadaf Ebrahimi 
1368*f5c631daSSadaf Ebrahimi   Emit(FMAXV_v_p_z | SVESize(zn) | Rd(vd) | PgLow8(pg) | Rn(zn));
1369*f5c631daSSadaf Ebrahimi }
1370*f5c631daSSadaf Ebrahimi 
fminnmv(const VRegister & vd,const PRegister & pg,const ZRegister & zn)1371*f5c631daSSadaf Ebrahimi void Assembler::fminnmv(const VRegister& vd,
1372*f5c631daSSadaf Ebrahimi                         const PRegister& pg,
1373*f5c631daSSadaf Ebrahimi                         const ZRegister& zn) {
1374*f5c631daSSadaf Ebrahimi   // FMINNMV <V><d>, <Pg>, <Zn>.<T>
1375*f5c631daSSadaf Ebrahimi   //  0110 0101 ..00 0101 001. .... .... ....
1376*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 101 | Pg<12:10> | Zn<9:5> | Vd<4:0>
1377*f5c631daSSadaf Ebrahimi 
1378*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1379*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(vd.IsScalar());
1380*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() != kBRegSizeInBytes);
1381*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, vd));
1382*f5c631daSSadaf Ebrahimi 
1383*f5c631daSSadaf Ebrahimi   Emit(FMINNMV_v_p_z | SVESize(zn) | Rd(vd) | PgLow8(pg) | Rn(zn));
1384*f5c631daSSadaf Ebrahimi }
1385*f5c631daSSadaf Ebrahimi 
fminv(const VRegister & vd,const PRegister & pg,const ZRegister & zn)1386*f5c631daSSadaf Ebrahimi void Assembler::fminv(const VRegister& vd,
1387*f5c631daSSadaf Ebrahimi                       const PRegister& pg,
1388*f5c631daSSadaf Ebrahimi                       const ZRegister& zn) {
1389*f5c631daSSadaf Ebrahimi   // FMINV <V><d>, <Pg>, <Zn>.<T>
1390*f5c631daSSadaf Ebrahimi   //  0110 0101 ..00 0111 001. .... .... ....
1391*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 111 | Pg<12:10> | Zn<9:5> | Vd<4:0>
1392*f5c631daSSadaf Ebrahimi 
1393*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1394*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(vd.IsScalar());
1395*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() != kBRegSizeInBytes);
1396*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, vd));
1397*f5c631daSSadaf Ebrahimi 
1398*f5c631daSSadaf Ebrahimi   Emit(FMINV_v_p_z | SVESize(zn) | Rd(vd) | PgLow8(pg) | Rn(zn));
1399*f5c631daSSadaf Ebrahimi }
1400*f5c631daSSadaf Ebrahimi 
1401*f5c631daSSadaf Ebrahimi // SVEFPMulAdd.
1402*f5c631daSSadaf Ebrahimi 
fmad(const ZRegister & zdn,const PRegisterM & pg,const ZRegister & zm,const ZRegister & za)1403*f5c631daSSadaf Ebrahimi void Assembler::fmad(const ZRegister& zdn,
1404*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
1405*f5c631daSSadaf Ebrahimi                      const ZRegister& zm,
1406*f5c631daSSadaf Ebrahimi                      const ZRegister& za) {
1407*f5c631daSSadaf Ebrahimi   // FMAD <Zdn>.<T>, <Pg>/M, <Zm>.<T>, <Za>.<T>
1408*f5c631daSSadaf Ebrahimi   //  0110 0101 ..1. .... 100. .... .... ....
1409*f5c631daSSadaf Ebrahimi   //  size<23:22> | Za<20:16> | opc<14:13> = 00 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
1410*f5c631daSSadaf Ebrahimi 
1411*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1412*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zdn, zm, za));
1413*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zdn.GetLaneSizeInBytes() != kBRegSizeInBytes);
1414*f5c631daSSadaf Ebrahimi 
1415*f5c631daSSadaf Ebrahimi   Emit(FMAD_z_p_zzz | SVESize(zdn) | Rd(zdn) | PgLow8(pg) | Rn(zm) | Rm(za));
1416*f5c631daSSadaf Ebrahimi }
1417*f5c631daSSadaf Ebrahimi 
fmla(const ZRegister & zda,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)1418*f5c631daSSadaf Ebrahimi void Assembler::fmla(const ZRegister& zda,
1419*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
1420*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
1421*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
1422*f5c631daSSadaf Ebrahimi   // FMLA <Zda>.<T>, <Pg>/M, <Zn>.<T>, <Zm>.<T>
1423*f5c631daSSadaf Ebrahimi   //  0110 0101 ..1. .... 000. .... .... ....
1424*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<14:13> = 00 | Pg<12:10> | Zn<9:5> | Zda<4:0>
1425*f5c631daSSadaf Ebrahimi 
1426*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1427*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn, zm));
1428*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() != kBRegSizeInBytes);
1429*f5c631daSSadaf Ebrahimi 
1430*f5c631daSSadaf Ebrahimi   Emit(FMLA_z_p_zzz | SVESize(zda) | Rd(zda) | PgLow8(pg) | Rn(zn) | Rm(zm));
1431*f5c631daSSadaf Ebrahimi }
1432*f5c631daSSadaf Ebrahimi 
fmls(const ZRegister & zda,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)1433*f5c631daSSadaf Ebrahimi void Assembler::fmls(const ZRegister& zda,
1434*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
1435*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
1436*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
1437*f5c631daSSadaf Ebrahimi   // FMLS <Zda>.<T>, <Pg>/M, <Zn>.<T>, <Zm>.<T>
1438*f5c631daSSadaf Ebrahimi   //  0110 0101 ..1. .... 001. .... .... ....
1439*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<14:13> = 01 | Pg<12:10> | Zn<9:5> | Zda<4:0>
1440*f5c631daSSadaf Ebrahimi 
1441*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1442*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn, zm));
1443*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() != kBRegSizeInBytes);
1444*f5c631daSSadaf Ebrahimi 
1445*f5c631daSSadaf Ebrahimi   Emit(FMLS_z_p_zzz | SVESize(zda) | Rd(zda) | PgLow8(pg) | Rn(zn) | Rm(zm));
1446*f5c631daSSadaf Ebrahimi }
1447*f5c631daSSadaf Ebrahimi 
fmsb(const ZRegister & zdn,const PRegisterM & pg,const ZRegister & zm,const ZRegister & za)1448*f5c631daSSadaf Ebrahimi void Assembler::fmsb(const ZRegister& zdn,
1449*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
1450*f5c631daSSadaf Ebrahimi                      const ZRegister& zm,
1451*f5c631daSSadaf Ebrahimi                      const ZRegister& za) {
1452*f5c631daSSadaf Ebrahimi   // FMSB <Zdn>.<T>, <Pg>/M, <Zm>.<T>, <Za>.<T>
1453*f5c631daSSadaf Ebrahimi   //  0110 0101 ..1. .... 101. .... .... ....
1454*f5c631daSSadaf Ebrahimi   //  size<23:22> | Za<20:16> | opc<14:13> = 01 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
1455*f5c631daSSadaf Ebrahimi 
1456*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1457*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zdn, zm, za));
1458*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zdn.GetLaneSizeInBytes() != kBRegSizeInBytes);
1459*f5c631daSSadaf Ebrahimi 
1460*f5c631daSSadaf Ebrahimi   Emit(FMSB_z_p_zzz | SVESize(zdn) | Rd(zdn) | PgLow8(pg) | Rn(zm) | Rm(za));
1461*f5c631daSSadaf Ebrahimi }
1462*f5c631daSSadaf Ebrahimi 
fnmad(const ZRegister & zdn,const PRegisterM & pg,const ZRegister & zm,const ZRegister & za)1463*f5c631daSSadaf Ebrahimi void Assembler::fnmad(const ZRegister& zdn,
1464*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
1465*f5c631daSSadaf Ebrahimi                       const ZRegister& zm,
1466*f5c631daSSadaf Ebrahimi                       const ZRegister& za) {
1467*f5c631daSSadaf Ebrahimi   // FNMAD <Zdn>.<T>, <Pg>/M, <Zm>.<T>, <Za>.<T>
1468*f5c631daSSadaf Ebrahimi   //  0110 0101 ..1. .... 110. .... .... ....
1469*f5c631daSSadaf Ebrahimi   //  size<23:22> | Za<20:16> | opc<14:13> = 10 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
1470*f5c631daSSadaf Ebrahimi 
1471*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1472*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zdn, zm, za));
1473*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zdn.GetLaneSizeInBytes() != kBRegSizeInBytes);
1474*f5c631daSSadaf Ebrahimi 
1475*f5c631daSSadaf Ebrahimi   Emit(FNMAD_z_p_zzz | SVESize(zdn) | Rd(zdn) | PgLow8(pg) | Rn(zm) | Rm(za));
1476*f5c631daSSadaf Ebrahimi }
1477*f5c631daSSadaf Ebrahimi 
fnmla(const ZRegister & zda,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)1478*f5c631daSSadaf Ebrahimi void Assembler::fnmla(const ZRegister& zda,
1479*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
1480*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
1481*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
1482*f5c631daSSadaf Ebrahimi   // FNMLA <Zda>.<T>, <Pg>/M, <Zn>.<T>, <Zm>.<T>
1483*f5c631daSSadaf Ebrahimi   //  0110 0101 ..1. .... 010. .... .... ....
1484*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<14:13> = 10 | Pg<12:10> | Zn<9:5> | Zda<4:0>
1485*f5c631daSSadaf Ebrahimi 
1486*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1487*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn, zm));
1488*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() != kBRegSizeInBytes);
1489*f5c631daSSadaf Ebrahimi 
1490*f5c631daSSadaf Ebrahimi   Emit(FNMLA_z_p_zzz | SVESize(zda) | Rd(zda) | PgLow8(pg) | Rn(zn) | Rm(zm));
1491*f5c631daSSadaf Ebrahimi }
1492*f5c631daSSadaf Ebrahimi 
fnmls(const ZRegister & zda,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)1493*f5c631daSSadaf Ebrahimi void Assembler::fnmls(const ZRegister& zda,
1494*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
1495*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
1496*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
1497*f5c631daSSadaf Ebrahimi   // FNMLS <Zda>.<T>, <Pg>/M, <Zn>.<T>, <Zm>.<T>
1498*f5c631daSSadaf Ebrahimi   //  0110 0101 ..1. .... 011. .... .... ....
1499*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<14:13> = 11 | Pg<12:10> | Zn<9:5> | Zda<4:0>
1500*f5c631daSSadaf Ebrahimi 
1501*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1502*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn, zm));
1503*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() != kBRegSizeInBytes);
1504*f5c631daSSadaf Ebrahimi 
1505*f5c631daSSadaf Ebrahimi   Emit(FNMLS_z_p_zzz | SVESize(zda) | Rd(zda) | PgLow8(pg) | Rn(zn) | Rm(zm));
1506*f5c631daSSadaf Ebrahimi }
1507*f5c631daSSadaf Ebrahimi 
fnmsb(const ZRegister & zdn,const PRegisterM & pg,const ZRegister & zm,const ZRegister & za)1508*f5c631daSSadaf Ebrahimi void Assembler::fnmsb(const ZRegister& zdn,
1509*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
1510*f5c631daSSadaf Ebrahimi                       const ZRegister& zm,
1511*f5c631daSSadaf Ebrahimi                       const ZRegister& za) {
1512*f5c631daSSadaf Ebrahimi   // FNMSB <Zdn>.<T>, <Pg>/M, <Zm>.<T>, <Za>.<T>
1513*f5c631daSSadaf Ebrahimi   //  0110 0101 ..1. .... 111. .... .... ....
1514*f5c631daSSadaf Ebrahimi   //  size<23:22> | Za<20:16> | opc<14:13> = 11 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
1515*f5c631daSSadaf Ebrahimi 
1516*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1517*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zdn, zm, za));
1518*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zdn.GetLaneSizeInBytes() != kBRegSizeInBytes);
1519*f5c631daSSadaf Ebrahimi 
1520*f5c631daSSadaf Ebrahimi   Emit(FNMSB_z_p_zzz | SVESize(zdn) | Rd(zdn) | PgLow8(pg) | Rn(zm) | Rm(za));
1521*f5c631daSSadaf Ebrahimi }
1522*f5c631daSSadaf Ebrahimi 
SVEMulIndexHelper(unsigned lane_size_in_bytes_log2,const ZRegister & zm,int index,Instr op_h,Instr op_s,Instr op_d)1523*f5c631daSSadaf Ebrahimi Instr Assembler::SVEMulIndexHelper(unsigned lane_size_in_bytes_log2,
1524*f5c631daSSadaf Ebrahimi                                    const ZRegister& zm,
1525*f5c631daSSadaf Ebrahimi                                    int index,
1526*f5c631daSSadaf Ebrahimi                                    Instr op_h,
1527*f5c631daSSadaf Ebrahimi                                    Instr op_s,
1528*f5c631daSSadaf Ebrahimi                                    Instr op_d) {
1529*f5c631daSSadaf Ebrahimi   Instr size = lane_size_in_bytes_log2 << SVESize_offset;
1530*f5c631daSSadaf Ebrahimi   Instr zm_with_index = Rm(zm);
1531*f5c631daSSadaf Ebrahimi   Instr op = 0xffffffff;
1532*f5c631daSSadaf Ebrahimi   // Allowable register number and lane index depends on the lane size.
1533*f5c631daSSadaf Ebrahimi   switch (lane_size_in_bytes_log2) {
1534*f5c631daSSadaf Ebrahimi     case kHRegSizeInBytesLog2:
1535*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(zm.GetCode() <= 7);
1536*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(IsUint3(index));
1537*f5c631daSSadaf Ebrahimi       // For H-sized lanes, size is encoded as 0b0x, where x is used as the top
1538*f5c631daSSadaf Ebrahimi       // bit of the index. So, if index is less than four, the top bit of index
1539*f5c631daSSadaf Ebrahimi       // is zero, and therefore size is 0b00. Otherwise, it's 0b01, the usual
1540*f5c631daSSadaf Ebrahimi       // encoding for H-sized lanes.
1541*f5c631daSSadaf Ebrahimi       if (index < 4) size = 0;
1542*f5c631daSSadaf Ebrahimi       // Top two bits of "zm" encode the index.
1543*f5c631daSSadaf Ebrahimi       zm_with_index |= (index & 3) << (Rm_offset + 3);
1544*f5c631daSSadaf Ebrahimi       op = op_h;
1545*f5c631daSSadaf Ebrahimi       break;
1546*f5c631daSSadaf Ebrahimi     case kSRegSizeInBytesLog2:
1547*f5c631daSSadaf Ebrahimi       VIXL_CHECK(zm.GetCode() <= 7);
1548*f5c631daSSadaf Ebrahimi       VIXL_CHECK(IsUint2(index));
1549*f5c631daSSadaf Ebrahimi       // Top two bits of "zm" encode the index.
1550*f5c631daSSadaf Ebrahimi       zm_with_index |= (index & 3) << (Rm_offset + 3);
1551*f5c631daSSadaf Ebrahimi       op = op_s;
1552*f5c631daSSadaf Ebrahimi       break;
1553*f5c631daSSadaf Ebrahimi     case kDRegSizeInBytesLog2:
1554*f5c631daSSadaf Ebrahimi       VIXL_CHECK(zm.GetCode() <= 15);
1555*f5c631daSSadaf Ebrahimi       VIXL_CHECK(IsUint1(index));
1556*f5c631daSSadaf Ebrahimi       // Top bit of "zm" encodes the index.
1557*f5c631daSSadaf Ebrahimi       zm_with_index |= (index & 1) << (Rm_offset + 4);
1558*f5c631daSSadaf Ebrahimi       op = op_d;
1559*f5c631daSSadaf Ebrahimi       break;
1560*f5c631daSSadaf Ebrahimi     default:
1561*f5c631daSSadaf Ebrahimi       VIXL_UNIMPLEMENTED();
1562*f5c631daSSadaf Ebrahimi   }
1563*f5c631daSSadaf Ebrahimi   return op | zm_with_index | size;
1564*f5c631daSSadaf Ebrahimi }
1565*f5c631daSSadaf Ebrahimi 
SVEMulLongIndexHelper(const ZRegister & zm,int index)1566*f5c631daSSadaf Ebrahimi Instr Assembler::SVEMulLongIndexHelper(const ZRegister& zm, int index) {
1567*f5c631daSSadaf Ebrahimi   Instr imm_field;
1568*f5c631daSSadaf Ebrahimi   Instr zm_id;
1569*f5c631daSSadaf Ebrahimi   if (zm.IsLaneSizeH()) {
1570*f5c631daSSadaf Ebrahimi     VIXL_CHECK(zm.GetCode() <= 7);
1571*f5c631daSSadaf Ebrahimi     VIXL_CHECK(IsUint3(index));
1572*f5c631daSSadaf Ebrahimi     imm_field = ExtractUnsignedBitfield32(2, 1, index) << 19;
1573*f5c631daSSadaf Ebrahimi     zm_id = Rx<18, 16>(zm);
1574*f5c631daSSadaf Ebrahimi   } else {
1575*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zm.IsLaneSizeS());
1576*f5c631daSSadaf Ebrahimi     VIXL_CHECK(zm.GetCode() <= 15);
1577*f5c631daSSadaf Ebrahimi     VIXL_CHECK(IsUint2(index));
1578*f5c631daSSadaf Ebrahimi     imm_field = ExtractBit(index, 1) << 20;
1579*f5c631daSSadaf Ebrahimi     zm_id = Rx<19, 16>(zm);
1580*f5c631daSSadaf Ebrahimi   }
1581*f5c631daSSadaf Ebrahimi 
1582*f5c631daSSadaf Ebrahimi   // Synthesize the low part of immediate encoding.
1583*f5c631daSSadaf Ebrahimi   imm_field |= ExtractBit(index, 0) << 11;
1584*f5c631daSSadaf Ebrahimi 
1585*f5c631daSSadaf Ebrahimi   return zm_id | imm_field;
1586*f5c631daSSadaf Ebrahimi }
1587*f5c631daSSadaf Ebrahimi 
SVEMulComplexIndexHelper(const ZRegister & zm,int index)1588*f5c631daSSadaf Ebrahimi Instr Assembler::SVEMulComplexIndexHelper(const ZRegister& zm, int index) {
1589*f5c631daSSadaf Ebrahimi   Instr zm_idx_size;
1590*f5c631daSSadaf Ebrahimi   if (zm.IsLaneSizeH()) {
1591*f5c631daSSadaf Ebrahimi     // Zm<18:16> | i2<20:19>
1592*f5c631daSSadaf Ebrahimi     VIXL_CHECK(zm.GetCode() <= 7);
1593*f5c631daSSadaf Ebrahimi     VIXL_CHECK(IsUint2(index));
1594*f5c631daSSadaf Ebrahimi     zm_idx_size = (index << 19) | Rx<18, 16>(zm) | 0;
1595*f5c631daSSadaf Ebrahimi   } else {
1596*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zm.IsLaneSizeS());
1597*f5c631daSSadaf Ebrahimi     // Zm<19:16> | i1<20>
1598*f5c631daSSadaf Ebrahimi     VIXL_CHECK(zm.GetCode() <= 15);
1599*f5c631daSSadaf Ebrahimi     VIXL_CHECK(IsUint1(index));
1600*f5c631daSSadaf Ebrahimi     zm_idx_size = (index << 20) | Rx<19, 16>(zm) | (1 << 22);
1601*f5c631daSSadaf Ebrahimi   }
1602*f5c631daSSadaf Ebrahimi   return zm_idx_size;
1603*f5c631daSSadaf Ebrahimi }
1604*f5c631daSSadaf Ebrahimi 
1605*f5c631daSSadaf Ebrahimi // SVEFPMulAddIndex.
1606*f5c631daSSadaf Ebrahimi 
fmla(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm,int index)1607*f5c631daSSadaf Ebrahimi void Assembler::fmla(const ZRegister& zda,
1608*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
1609*f5c631daSSadaf Ebrahimi                      const ZRegister& zm,
1610*f5c631daSSadaf Ebrahimi                      int index) {
1611*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1612*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn, zm));
1613*f5c631daSSadaf Ebrahimi 
1614*f5c631daSSadaf Ebrahimi   // The encoding of opcode, index, Zm, and size are synthesized in this
1615*f5c631daSSadaf Ebrahimi   // variable.
1616*f5c631daSSadaf Ebrahimi   Instr synthesized_op = SVEMulIndexHelper(zda.GetLaneSizeInBytesLog2(),
1617*f5c631daSSadaf Ebrahimi                                            zm,
1618*f5c631daSSadaf Ebrahimi                                            index,
1619*f5c631daSSadaf Ebrahimi                                            FMLA_z_zzzi_h,
1620*f5c631daSSadaf Ebrahimi                                            FMLA_z_zzzi_s,
1621*f5c631daSSadaf Ebrahimi                                            FMLA_z_zzzi_d);
1622*f5c631daSSadaf Ebrahimi 
1623*f5c631daSSadaf Ebrahimi   Emit(synthesized_op | Rd(zda) | Rn(zn));
1624*f5c631daSSadaf Ebrahimi }
1625*f5c631daSSadaf Ebrahimi 
fmls(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm,int index)1626*f5c631daSSadaf Ebrahimi void Assembler::fmls(const ZRegister& zda,
1627*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
1628*f5c631daSSadaf Ebrahimi                      const ZRegister& zm,
1629*f5c631daSSadaf Ebrahimi                      int index) {
1630*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1631*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn, zm));
1632*f5c631daSSadaf Ebrahimi 
1633*f5c631daSSadaf Ebrahimi   // The encoding of opcode, index, Zm, and size are synthesized in this
1634*f5c631daSSadaf Ebrahimi   // variable.
1635*f5c631daSSadaf Ebrahimi   Instr synthesized_op = SVEMulIndexHelper(zda.GetLaneSizeInBytesLog2(),
1636*f5c631daSSadaf Ebrahimi                                            zm,
1637*f5c631daSSadaf Ebrahimi                                            index,
1638*f5c631daSSadaf Ebrahimi                                            FMLS_z_zzzi_h,
1639*f5c631daSSadaf Ebrahimi                                            FMLS_z_zzzi_s,
1640*f5c631daSSadaf Ebrahimi                                            FMLS_z_zzzi_d);
1641*f5c631daSSadaf Ebrahimi 
1642*f5c631daSSadaf Ebrahimi   Emit(synthesized_op | Rd(zda) | Rn(zn));
1643*f5c631daSSadaf Ebrahimi }
1644*f5c631daSSadaf Ebrahimi 
1645*f5c631daSSadaf Ebrahimi // SVEFPMulIndex.
1646*f5c631daSSadaf Ebrahimi 
1647*f5c631daSSadaf Ebrahimi // This prototype maps to 3 instruction encodings:
fmul(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm,unsigned index)1648*f5c631daSSadaf Ebrahimi void Assembler::fmul(const ZRegister& zd,
1649*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
1650*f5c631daSSadaf Ebrahimi                      const ZRegister& zm,
1651*f5c631daSSadaf Ebrahimi                      unsigned index) {
1652*f5c631daSSadaf Ebrahimi   // FMUL <Zd>.<T>, <Zn>.<T>, <Zm>.<T>[<imm>]
1653*f5c631daSSadaf Ebrahimi   //  0110 0100 ..1. .... 0010 00.. .... ....
1654*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<20:16> | Zn<9:5> | Zd<4:0>
1655*f5c631daSSadaf Ebrahimi 
1656*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1657*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
1658*f5c631daSSadaf Ebrahimi 
1659*f5c631daSSadaf Ebrahimi   // The encoding of opcode, index, Zm, and size are synthesized in this
1660*f5c631daSSadaf Ebrahimi   // variable.
1661*f5c631daSSadaf Ebrahimi   Instr synthesized_op = SVEMulIndexHelper(zd.GetLaneSizeInBytesLog2(),
1662*f5c631daSSadaf Ebrahimi                                            zm,
1663*f5c631daSSadaf Ebrahimi                                            index,
1664*f5c631daSSadaf Ebrahimi                                            FMUL_z_zzi_h,
1665*f5c631daSSadaf Ebrahimi                                            FMUL_z_zzi_s,
1666*f5c631daSSadaf Ebrahimi                                            FMUL_z_zzi_d);
1667*f5c631daSSadaf Ebrahimi 
1668*f5c631daSSadaf Ebrahimi   Emit(synthesized_op | Rd(zd) | Rn(zn));
1669*f5c631daSSadaf Ebrahimi }
1670*f5c631daSSadaf Ebrahimi 
1671*f5c631daSSadaf Ebrahimi // SVEFPUnaryOpPredicated.
1672*f5c631daSSadaf Ebrahimi 
fcvt(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)1673*f5c631daSSadaf Ebrahimi void Assembler::fcvt(const ZRegister& zd,
1674*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
1675*f5c631daSSadaf Ebrahimi                      const ZRegister& zn) {
1676*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1677*f5c631daSSadaf Ebrahimi 
1678*f5c631daSSadaf Ebrahimi   Instr op = 0xffffffff;
1679*f5c631daSSadaf Ebrahimi   switch (zn.GetLaneSizeInBytes()) {
1680*f5c631daSSadaf Ebrahimi     case kHRegSizeInBytes:
1681*f5c631daSSadaf Ebrahimi       switch (zd.GetLaneSizeInBytes()) {
1682*f5c631daSSadaf Ebrahimi         case kSRegSizeInBytes:
1683*f5c631daSSadaf Ebrahimi           op = FCVT_z_p_z_h2s;
1684*f5c631daSSadaf Ebrahimi           break;
1685*f5c631daSSadaf Ebrahimi         case kDRegSizeInBytes:
1686*f5c631daSSadaf Ebrahimi           op = FCVT_z_p_z_h2d;
1687*f5c631daSSadaf Ebrahimi           break;
1688*f5c631daSSadaf Ebrahimi       }
1689*f5c631daSSadaf Ebrahimi       break;
1690*f5c631daSSadaf Ebrahimi     case kSRegSizeInBytes:
1691*f5c631daSSadaf Ebrahimi       switch (zd.GetLaneSizeInBytes()) {
1692*f5c631daSSadaf Ebrahimi         case kHRegSizeInBytes:
1693*f5c631daSSadaf Ebrahimi           op = FCVT_z_p_z_s2h;
1694*f5c631daSSadaf Ebrahimi           break;
1695*f5c631daSSadaf Ebrahimi         case kDRegSizeInBytes:
1696*f5c631daSSadaf Ebrahimi           op = FCVT_z_p_z_s2d;
1697*f5c631daSSadaf Ebrahimi           break;
1698*f5c631daSSadaf Ebrahimi       }
1699*f5c631daSSadaf Ebrahimi       break;
1700*f5c631daSSadaf Ebrahimi     case kDRegSizeInBytes:
1701*f5c631daSSadaf Ebrahimi       switch (zd.GetLaneSizeInBytes()) {
1702*f5c631daSSadaf Ebrahimi         case kHRegSizeInBytes:
1703*f5c631daSSadaf Ebrahimi           op = FCVT_z_p_z_d2h;
1704*f5c631daSSadaf Ebrahimi           break;
1705*f5c631daSSadaf Ebrahimi         case kSRegSizeInBytes:
1706*f5c631daSSadaf Ebrahimi           op = FCVT_z_p_z_d2s;
1707*f5c631daSSadaf Ebrahimi           break;
1708*f5c631daSSadaf Ebrahimi       }
1709*f5c631daSSadaf Ebrahimi       break;
1710*f5c631daSSadaf Ebrahimi   }
1711*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(op != 0xffffffff);
1712*f5c631daSSadaf Ebrahimi 
1713*f5c631daSSadaf Ebrahimi   Emit(op | Rd(zd) | PgLow8(pg) | Rn(zn));
1714*f5c631daSSadaf Ebrahimi }
1715*f5c631daSSadaf Ebrahimi 
fcvtzs(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)1716*f5c631daSSadaf Ebrahimi void Assembler::fcvtzs(const ZRegister& zd,
1717*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
1718*f5c631daSSadaf Ebrahimi                        const ZRegister& zn) {
1719*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1720*f5c631daSSadaf Ebrahimi   Instr op = 0xffffffff;
1721*f5c631daSSadaf Ebrahimi   switch (zn.GetLaneSizeInBytes()) {
1722*f5c631daSSadaf Ebrahimi     case kHRegSizeInBytes:
1723*f5c631daSSadaf Ebrahimi       switch (zd.GetLaneSizeInBytes()) {
1724*f5c631daSSadaf Ebrahimi         case kHRegSizeInBytes:
1725*f5c631daSSadaf Ebrahimi           op = FCVTZS_z_p_z_fp162h;
1726*f5c631daSSadaf Ebrahimi           break;
1727*f5c631daSSadaf Ebrahimi         case kSRegSizeInBytes:
1728*f5c631daSSadaf Ebrahimi           op = FCVTZS_z_p_z_fp162w;
1729*f5c631daSSadaf Ebrahimi           break;
1730*f5c631daSSadaf Ebrahimi         case kDRegSizeInBytes:
1731*f5c631daSSadaf Ebrahimi           op = FCVTZS_z_p_z_fp162x;
1732*f5c631daSSadaf Ebrahimi           break;
1733*f5c631daSSadaf Ebrahimi       }
1734*f5c631daSSadaf Ebrahimi       break;
1735*f5c631daSSadaf Ebrahimi     case kSRegSizeInBytes:
1736*f5c631daSSadaf Ebrahimi       switch (zd.GetLaneSizeInBytes()) {
1737*f5c631daSSadaf Ebrahimi         case kSRegSizeInBytes:
1738*f5c631daSSadaf Ebrahimi           op = FCVTZS_z_p_z_s2w;
1739*f5c631daSSadaf Ebrahimi           break;
1740*f5c631daSSadaf Ebrahimi         case kDRegSizeInBytes:
1741*f5c631daSSadaf Ebrahimi           op = FCVTZS_z_p_z_s2x;
1742*f5c631daSSadaf Ebrahimi           break;
1743*f5c631daSSadaf Ebrahimi       }
1744*f5c631daSSadaf Ebrahimi       break;
1745*f5c631daSSadaf Ebrahimi     case kDRegSizeInBytes:
1746*f5c631daSSadaf Ebrahimi       switch (zd.GetLaneSizeInBytes()) {
1747*f5c631daSSadaf Ebrahimi         case kSRegSizeInBytes:
1748*f5c631daSSadaf Ebrahimi           op = FCVTZS_z_p_z_d2w;
1749*f5c631daSSadaf Ebrahimi           break;
1750*f5c631daSSadaf Ebrahimi         case kDRegSizeInBytes:
1751*f5c631daSSadaf Ebrahimi           op = FCVTZS_z_p_z_d2x;
1752*f5c631daSSadaf Ebrahimi           break;
1753*f5c631daSSadaf Ebrahimi       }
1754*f5c631daSSadaf Ebrahimi       break;
1755*f5c631daSSadaf Ebrahimi   }
1756*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(op != 0xffffffff);
1757*f5c631daSSadaf Ebrahimi 
1758*f5c631daSSadaf Ebrahimi   Emit(op | Rd(zd) | PgLow8(pg) | Rn(zn));
1759*f5c631daSSadaf Ebrahimi }
1760*f5c631daSSadaf Ebrahimi 
fcvtzu(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)1761*f5c631daSSadaf Ebrahimi void Assembler::fcvtzu(const ZRegister& zd,
1762*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
1763*f5c631daSSadaf Ebrahimi                        const ZRegister& zn) {
1764*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1765*f5c631daSSadaf Ebrahimi   Instr op = 0xffffffff;
1766*f5c631daSSadaf Ebrahimi   switch (zn.GetLaneSizeInBytes()) {
1767*f5c631daSSadaf Ebrahimi     case kHRegSizeInBytes:
1768*f5c631daSSadaf Ebrahimi       switch (zd.GetLaneSizeInBytes()) {
1769*f5c631daSSadaf Ebrahimi         case kHRegSizeInBytes:
1770*f5c631daSSadaf Ebrahimi           op = FCVTZU_z_p_z_fp162h;
1771*f5c631daSSadaf Ebrahimi           break;
1772*f5c631daSSadaf Ebrahimi         case kSRegSizeInBytes:
1773*f5c631daSSadaf Ebrahimi           op = FCVTZU_z_p_z_fp162w;
1774*f5c631daSSadaf Ebrahimi           break;
1775*f5c631daSSadaf Ebrahimi         case kDRegSizeInBytes:
1776*f5c631daSSadaf Ebrahimi           op = FCVTZU_z_p_z_fp162x;
1777*f5c631daSSadaf Ebrahimi           break;
1778*f5c631daSSadaf Ebrahimi       }
1779*f5c631daSSadaf Ebrahimi       break;
1780*f5c631daSSadaf Ebrahimi     case kSRegSizeInBytes:
1781*f5c631daSSadaf Ebrahimi       switch (zd.GetLaneSizeInBytes()) {
1782*f5c631daSSadaf Ebrahimi         case kSRegSizeInBytes:
1783*f5c631daSSadaf Ebrahimi           op = FCVTZU_z_p_z_s2w;
1784*f5c631daSSadaf Ebrahimi           break;
1785*f5c631daSSadaf Ebrahimi         case kDRegSizeInBytes:
1786*f5c631daSSadaf Ebrahimi           op = FCVTZU_z_p_z_s2x;
1787*f5c631daSSadaf Ebrahimi           break;
1788*f5c631daSSadaf Ebrahimi       }
1789*f5c631daSSadaf Ebrahimi       break;
1790*f5c631daSSadaf Ebrahimi     case kDRegSizeInBytes:
1791*f5c631daSSadaf Ebrahimi       switch (zd.GetLaneSizeInBytes()) {
1792*f5c631daSSadaf Ebrahimi         case kSRegSizeInBytes:
1793*f5c631daSSadaf Ebrahimi           op = FCVTZU_z_p_z_d2w;
1794*f5c631daSSadaf Ebrahimi           break;
1795*f5c631daSSadaf Ebrahimi         case kDRegSizeInBytes:
1796*f5c631daSSadaf Ebrahimi           op = FCVTZU_z_p_z_d2x;
1797*f5c631daSSadaf Ebrahimi           break;
1798*f5c631daSSadaf Ebrahimi       }
1799*f5c631daSSadaf Ebrahimi       break;
1800*f5c631daSSadaf Ebrahimi   }
1801*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(op != 0xffffffff);
1802*f5c631daSSadaf Ebrahimi 
1803*f5c631daSSadaf Ebrahimi   Emit(op | Rd(zd) | PgLow8(pg) | Rn(zn));
1804*f5c631daSSadaf Ebrahimi }
1805*f5c631daSSadaf Ebrahimi 
frecpx(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)1806*f5c631daSSadaf Ebrahimi void Assembler::frecpx(const ZRegister& zd,
1807*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
1808*f5c631daSSadaf Ebrahimi                        const ZRegister& zn) {
1809*f5c631daSSadaf Ebrahimi   // FRECPX <Zd>.<T>, <Pg>/M, <Zn>.<T>
1810*f5c631daSSadaf Ebrahimi   //  0110 0101 ..00 1100 101. .... .... ....
1811*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<17:16> = 00 | Pg<12:10> | Zn<9:5> | Zd<4:0>
1812*f5c631daSSadaf Ebrahimi 
1813*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1814*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
1815*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
1816*f5c631daSSadaf Ebrahimi 
1817*f5c631daSSadaf Ebrahimi   Emit(FRECPX_z_p_z | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
1818*f5c631daSSadaf Ebrahimi }
1819*f5c631daSSadaf Ebrahimi 
frinta(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)1820*f5c631daSSadaf Ebrahimi void Assembler::frinta(const ZRegister& zd,
1821*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
1822*f5c631daSSadaf Ebrahimi                        const ZRegister& zn) {
1823*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1824*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
1825*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
1826*f5c631daSSadaf Ebrahimi 
1827*f5c631daSSadaf Ebrahimi   Emit(FRINTA_z_p_z | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
1828*f5c631daSSadaf Ebrahimi }
1829*f5c631daSSadaf Ebrahimi 
frinti(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)1830*f5c631daSSadaf Ebrahimi void Assembler::frinti(const ZRegister& zd,
1831*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
1832*f5c631daSSadaf Ebrahimi                        const ZRegister& zn) {
1833*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1834*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
1835*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
1836*f5c631daSSadaf Ebrahimi 
1837*f5c631daSSadaf Ebrahimi   Emit(FRINTI_z_p_z | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
1838*f5c631daSSadaf Ebrahimi }
1839*f5c631daSSadaf Ebrahimi 
frintm(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)1840*f5c631daSSadaf Ebrahimi void Assembler::frintm(const ZRegister& zd,
1841*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
1842*f5c631daSSadaf Ebrahimi                        const ZRegister& zn) {
1843*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1844*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
1845*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
1846*f5c631daSSadaf Ebrahimi 
1847*f5c631daSSadaf Ebrahimi   Emit(FRINTM_z_p_z | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
1848*f5c631daSSadaf Ebrahimi }
1849*f5c631daSSadaf Ebrahimi 
frintn(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)1850*f5c631daSSadaf Ebrahimi void Assembler::frintn(const ZRegister& zd,
1851*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
1852*f5c631daSSadaf Ebrahimi                        const ZRegister& zn) {
1853*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1854*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
1855*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
1856*f5c631daSSadaf Ebrahimi 
1857*f5c631daSSadaf Ebrahimi   Emit(FRINTN_z_p_z | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
1858*f5c631daSSadaf Ebrahimi }
1859*f5c631daSSadaf Ebrahimi 
frintp(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)1860*f5c631daSSadaf Ebrahimi void Assembler::frintp(const ZRegister& zd,
1861*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
1862*f5c631daSSadaf Ebrahimi                        const ZRegister& zn) {
1863*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1864*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
1865*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
1866*f5c631daSSadaf Ebrahimi 
1867*f5c631daSSadaf Ebrahimi   Emit(FRINTP_z_p_z | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
1868*f5c631daSSadaf Ebrahimi }
1869*f5c631daSSadaf Ebrahimi 
frintx(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)1870*f5c631daSSadaf Ebrahimi void Assembler::frintx(const ZRegister& zd,
1871*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
1872*f5c631daSSadaf Ebrahimi                        const ZRegister& zn) {
1873*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1874*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
1875*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
1876*f5c631daSSadaf Ebrahimi 
1877*f5c631daSSadaf Ebrahimi   Emit(FRINTX_z_p_z | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
1878*f5c631daSSadaf Ebrahimi }
1879*f5c631daSSadaf Ebrahimi 
frintz(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)1880*f5c631daSSadaf Ebrahimi void Assembler::frintz(const ZRegister& zd,
1881*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
1882*f5c631daSSadaf Ebrahimi                        const ZRegister& zn) {
1883*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1884*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
1885*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
1886*f5c631daSSadaf Ebrahimi 
1887*f5c631daSSadaf Ebrahimi   Emit(FRINTZ_z_p_z | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
1888*f5c631daSSadaf Ebrahimi }
1889*f5c631daSSadaf Ebrahimi 
fsqrt(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)1890*f5c631daSSadaf Ebrahimi void Assembler::fsqrt(const ZRegister& zd,
1891*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
1892*f5c631daSSadaf Ebrahimi                       const ZRegister& zn) {
1893*f5c631daSSadaf Ebrahimi   // FSQRT <Zd>.<T>, <Pg>/M, <Zn>.<T>
1894*f5c631daSSadaf Ebrahimi   //  0110 0101 ..00 1101 101. .... .... ....
1895*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<17:16> = 01 | Pg<12:10> | Zn<9:5> | Zd<4:0>
1896*f5c631daSSadaf Ebrahimi 
1897*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1898*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
1899*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
1900*f5c631daSSadaf Ebrahimi 
1901*f5c631daSSadaf Ebrahimi   Emit(FSQRT_z_p_z | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
1902*f5c631daSSadaf Ebrahimi }
1903*f5c631daSSadaf Ebrahimi 
scvtf(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)1904*f5c631daSSadaf Ebrahimi void Assembler::scvtf(const ZRegister& zd,
1905*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
1906*f5c631daSSadaf Ebrahimi                       const ZRegister& zn) {
1907*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1908*f5c631daSSadaf Ebrahimi   Instr op = 0xffffffff;
1909*f5c631daSSadaf Ebrahimi   switch (zn.GetLaneSizeInBytes()) {
1910*f5c631daSSadaf Ebrahimi     case kHRegSizeInBytes:
1911*f5c631daSSadaf Ebrahimi       switch (zd.GetLaneSizeInBytes()) {
1912*f5c631daSSadaf Ebrahimi         case kHRegSizeInBytes:
1913*f5c631daSSadaf Ebrahimi           op = SCVTF_z_p_z_h2fp16;
1914*f5c631daSSadaf Ebrahimi           break;
1915*f5c631daSSadaf Ebrahimi       }
1916*f5c631daSSadaf Ebrahimi       break;
1917*f5c631daSSadaf Ebrahimi     case kSRegSizeInBytes:
1918*f5c631daSSadaf Ebrahimi       switch (zd.GetLaneSizeInBytes()) {
1919*f5c631daSSadaf Ebrahimi         case kHRegSizeInBytes:
1920*f5c631daSSadaf Ebrahimi           op = SCVTF_z_p_z_w2fp16;
1921*f5c631daSSadaf Ebrahimi           break;
1922*f5c631daSSadaf Ebrahimi         case kSRegSizeInBytes:
1923*f5c631daSSadaf Ebrahimi           op = SCVTF_z_p_z_w2s;
1924*f5c631daSSadaf Ebrahimi           break;
1925*f5c631daSSadaf Ebrahimi         case kDRegSizeInBytes:
1926*f5c631daSSadaf Ebrahimi           op = SCVTF_z_p_z_w2d;
1927*f5c631daSSadaf Ebrahimi           break;
1928*f5c631daSSadaf Ebrahimi       }
1929*f5c631daSSadaf Ebrahimi       break;
1930*f5c631daSSadaf Ebrahimi     case kDRegSizeInBytes:
1931*f5c631daSSadaf Ebrahimi       switch (zd.GetLaneSizeInBytes()) {
1932*f5c631daSSadaf Ebrahimi         case kHRegSizeInBytes:
1933*f5c631daSSadaf Ebrahimi           op = SCVTF_z_p_z_x2fp16;
1934*f5c631daSSadaf Ebrahimi           break;
1935*f5c631daSSadaf Ebrahimi         case kSRegSizeInBytes:
1936*f5c631daSSadaf Ebrahimi           op = SCVTF_z_p_z_x2s;
1937*f5c631daSSadaf Ebrahimi           break;
1938*f5c631daSSadaf Ebrahimi         case kDRegSizeInBytes:
1939*f5c631daSSadaf Ebrahimi           op = SCVTF_z_p_z_x2d;
1940*f5c631daSSadaf Ebrahimi           break;
1941*f5c631daSSadaf Ebrahimi       }
1942*f5c631daSSadaf Ebrahimi       break;
1943*f5c631daSSadaf Ebrahimi   }
1944*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(op != 0xffffffff);
1945*f5c631daSSadaf Ebrahimi 
1946*f5c631daSSadaf Ebrahimi   Emit(op | Rd(zd) | PgLow8(pg) | Rn(zn));
1947*f5c631daSSadaf Ebrahimi }
1948*f5c631daSSadaf Ebrahimi 
ucvtf(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)1949*f5c631daSSadaf Ebrahimi void Assembler::ucvtf(const ZRegister& zd,
1950*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
1951*f5c631daSSadaf Ebrahimi                       const ZRegister& zn) {
1952*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
1953*f5c631daSSadaf Ebrahimi   Instr op = 0xffffffff;
1954*f5c631daSSadaf Ebrahimi   switch (zn.GetLaneSizeInBytes()) {
1955*f5c631daSSadaf Ebrahimi     case kHRegSizeInBytes:
1956*f5c631daSSadaf Ebrahimi       switch (zd.GetLaneSizeInBytes()) {
1957*f5c631daSSadaf Ebrahimi         case kHRegSizeInBytes:
1958*f5c631daSSadaf Ebrahimi           op = UCVTF_z_p_z_h2fp16;
1959*f5c631daSSadaf Ebrahimi           break;
1960*f5c631daSSadaf Ebrahimi       }
1961*f5c631daSSadaf Ebrahimi       break;
1962*f5c631daSSadaf Ebrahimi     case kSRegSizeInBytes:
1963*f5c631daSSadaf Ebrahimi       switch (zd.GetLaneSizeInBytes()) {
1964*f5c631daSSadaf Ebrahimi         case kHRegSizeInBytes:
1965*f5c631daSSadaf Ebrahimi           op = UCVTF_z_p_z_w2fp16;
1966*f5c631daSSadaf Ebrahimi           break;
1967*f5c631daSSadaf Ebrahimi         case kSRegSizeInBytes:
1968*f5c631daSSadaf Ebrahimi           op = UCVTF_z_p_z_w2s;
1969*f5c631daSSadaf Ebrahimi           break;
1970*f5c631daSSadaf Ebrahimi         case kDRegSizeInBytes:
1971*f5c631daSSadaf Ebrahimi           op = UCVTF_z_p_z_w2d;
1972*f5c631daSSadaf Ebrahimi           break;
1973*f5c631daSSadaf Ebrahimi       }
1974*f5c631daSSadaf Ebrahimi       break;
1975*f5c631daSSadaf Ebrahimi     case kDRegSizeInBytes:
1976*f5c631daSSadaf Ebrahimi       switch (zd.GetLaneSizeInBytes()) {
1977*f5c631daSSadaf Ebrahimi         case kHRegSizeInBytes:
1978*f5c631daSSadaf Ebrahimi           op = UCVTF_z_p_z_x2fp16;
1979*f5c631daSSadaf Ebrahimi           break;
1980*f5c631daSSadaf Ebrahimi         case kSRegSizeInBytes:
1981*f5c631daSSadaf Ebrahimi           op = UCVTF_z_p_z_x2s;
1982*f5c631daSSadaf Ebrahimi           break;
1983*f5c631daSSadaf Ebrahimi         case kDRegSizeInBytes:
1984*f5c631daSSadaf Ebrahimi           op = UCVTF_z_p_z_x2d;
1985*f5c631daSSadaf Ebrahimi           break;
1986*f5c631daSSadaf Ebrahimi       }
1987*f5c631daSSadaf Ebrahimi       break;
1988*f5c631daSSadaf Ebrahimi   }
1989*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(op != 0xffffffff);
1990*f5c631daSSadaf Ebrahimi 
1991*f5c631daSSadaf Ebrahimi   Emit(op | Rd(zd) | PgLow8(pg) | Rn(zn));
1992*f5c631daSSadaf Ebrahimi }
1993*f5c631daSSadaf Ebrahimi 
1994*f5c631daSSadaf Ebrahimi // SVEFPUnaryOpUnpredicated.
1995*f5c631daSSadaf Ebrahimi 
frecpe(const ZRegister & zd,const ZRegister & zn)1996*f5c631daSSadaf Ebrahimi void Assembler::frecpe(const ZRegister& zd, const ZRegister& zn) {
1997*f5c631daSSadaf Ebrahimi   // FRECPE <Zd>.<T>, <Zn>.<T>
1998*f5c631daSSadaf Ebrahimi   //  0110 0101 ..00 1110 0011 00.. .... ....
1999*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 110 | Zn<9:5> | Zd<4:0>
2000*f5c631daSSadaf Ebrahimi 
2001*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2002*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
2003*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
2004*f5c631daSSadaf Ebrahimi 
2005*f5c631daSSadaf Ebrahimi   Emit(FRECPE_z_z | SVESize(zd) | Rd(zd) | Rn(zn));
2006*f5c631daSSadaf Ebrahimi }
2007*f5c631daSSadaf Ebrahimi 
frsqrte(const ZRegister & zd,const ZRegister & zn)2008*f5c631daSSadaf Ebrahimi void Assembler::frsqrte(const ZRegister& zd, const ZRegister& zn) {
2009*f5c631daSSadaf Ebrahimi   // FRSQRTE <Zd>.<T>, <Zn>.<T>
2010*f5c631daSSadaf Ebrahimi   //  0110 0101 ..00 1111 0011 00.. .... ....
2011*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 111 | Zn<9:5> | Zd<4:0>
2012*f5c631daSSadaf Ebrahimi 
2013*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2014*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
2015*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
2016*f5c631daSSadaf Ebrahimi 
2017*f5c631daSSadaf Ebrahimi   Emit(FRSQRTE_z_z | SVESize(zd) | Rd(zd) | Rn(zn));
2018*f5c631daSSadaf Ebrahimi }
2019*f5c631daSSadaf Ebrahimi 
2020*f5c631daSSadaf Ebrahimi // SVEIncDecByPredicateCount.
2021*f5c631daSSadaf Ebrahimi 
decp(const Register & rdn,const PRegisterWithLaneSize & pg)2022*f5c631daSSadaf Ebrahimi void Assembler::decp(const Register& rdn, const PRegisterWithLaneSize& pg) {
2023*f5c631daSSadaf Ebrahimi   // DECP <Xdn>, <Pg>.<T>
2024*f5c631daSSadaf Ebrahimi   //  0010 0101 ..10 1101 1000 100. .... ....
2025*f5c631daSSadaf Ebrahimi   //  size<23:22> | op<17> = 0 | D<16> = 1 | opc2<10:9> = 00 | Pg<8:5> |
2026*f5c631daSSadaf Ebrahimi   //  Rdn<4:0>
2027*f5c631daSSadaf Ebrahimi 
2028*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2029*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(rdn.IsX());
2030*f5c631daSSadaf Ebrahimi 
2031*f5c631daSSadaf Ebrahimi   Emit(DECP_r_p_r | SVESize(pg) | Rd(rdn) | Rx<8, 5>(pg));
2032*f5c631daSSadaf Ebrahimi }
2033*f5c631daSSadaf Ebrahimi 
decp(const ZRegister & zdn,const PRegister & pg)2034*f5c631daSSadaf Ebrahimi void Assembler::decp(const ZRegister& zdn, const PRegister& pg) {
2035*f5c631daSSadaf Ebrahimi   // DECP <Zdn>.<T>, <Pg>
2036*f5c631daSSadaf Ebrahimi   //  0010 0101 ..10 1101 1000 000. .... ....
2037*f5c631daSSadaf Ebrahimi   //  size<23:22> | op<17> = 0 | D<16> = 1 | opc2<10:9> = 00 | Pg<8:5> |
2038*f5c631daSSadaf Ebrahimi   //  Zdn<4:0>
2039*f5c631daSSadaf Ebrahimi 
2040*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2041*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zdn.GetLaneSizeInBytes() != kBRegSizeInBytes);
2042*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pg.IsUnqualified());
2043*f5c631daSSadaf Ebrahimi 
2044*f5c631daSSadaf Ebrahimi   Emit(DECP_z_p_z | SVESize(zdn) | Rd(zdn) | Pg<8, 5>(pg));
2045*f5c631daSSadaf Ebrahimi }
2046*f5c631daSSadaf Ebrahimi 
incp(const Register & rdn,const PRegisterWithLaneSize & pg)2047*f5c631daSSadaf Ebrahimi void Assembler::incp(const Register& rdn, const PRegisterWithLaneSize& pg) {
2048*f5c631daSSadaf Ebrahimi   // INCP <Xdn>, <Pg>.<T>
2049*f5c631daSSadaf Ebrahimi   //  0010 0101 ..10 1100 1000 100. .... ....
2050*f5c631daSSadaf Ebrahimi   //  size<23:22> | op<17> = 0 | D<16> = 0 | opc2<10:9> = 00 | Pg<8:5> |
2051*f5c631daSSadaf Ebrahimi   //  Rdn<4:0>
2052*f5c631daSSadaf Ebrahimi 
2053*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2054*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(rdn.IsX());
2055*f5c631daSSadaf Ebrahimi 
2056*f5c631daSSadaf Ebrahimi   Emit(INCP_r_p_r | SVESize(pg) | Rd(rdn) | Rx<8, 5>(pg));
2057*f5c631daSSadaf Ebrahimi }
2058*f5c631daSSadaf Ebrahimi 
incp(const ZRegister & zdn,const PRegister & pg)2059*f5c631daSSadaf Ebrahimi void Assembler::incp(const ZRegister& zdn, const PRegister& pg) {
2060*f5c631daSSadaf Ebrahimi   // INCP <Zdn>.<T>, <Pg>
2061*f5c631daSSadaf Ebrahimi   //  0010 0101 ..10 1100 1000 000. .... ....
2062*f5c631daSSadaf Ebrahimi   //  size<23:22> | op<17> = 0 | D<16> = 0 | opc2<10:9> = 00 | Pg<8:5> |
2063*f5c631daSSadaf Ebrahimi   //  Zdn<4:0>
2064*f5c631daSSadaf Ebrahimi 
2065*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2066*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zdn.GetLaneSizeInBytes() != kBRegSizeInBytes);
2067*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pg.IsUnqualified());
2068*f5c631daSSadaf Ebrahimi 
2069*f5c631daSSadaf Ebrahimi   Emit(INCP_z_p_z | SVESize(zdn) | Rd(zdn) | Pg<8, 5>(pg));
2070*f5c631daSSadaf Ebrahimi }
2071*f5c631daSSadaf Ebrahimi 
sqdecp(const Register & xd,const PRegisterWithLaneSize & pg,const Register & wn)2072*f5c631daSSadaf Ebrahimi void Assembler::sqdecp(const Register& xd,
2073*f5c631daSSadaf Ebrahimi                        const PRegisterWithLaneSize& pg,
2074*f5c631daSSadaf Ebrahimi                        const Register& wn) {
2075*f5c631daSSadaf Ebrahimi   // SQDECP <Xdn>, <Pg>.<T>, <Wdn>
2076*f5c631daSSadaf Ebrahimi   //  0010 0101 ..10 1010 1000 100. .... ....
2077*f5c631daSSadaf Ebrahimi   //  size<23:22> | D<17> = 1 | U<16> = 0 | sf<10> = 0 | op<9> = 0 | Pg<8:5> |
2078*f5c631daSSadaf Ebrahimi   //  Rdn<4:0>
2079*f5c631daSSadaf Ebrahimi 
2080*f5c631daSSadaf Ebrahimi   USE(wn);
2081*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2082*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(xd.IsX() && wn.IsW() && xd.Aliases(wn));
2083*f5c631daSSadaf Ebrahimi 
2084*f5c631daSSadaf Ebrahimi   Emit(SQDECP_r_p_r_sx | SVESize(pg) | Rd(xd) | Rx<8, 5>(pg));
2085*f5c631daSSadaf Ebrahimi }
2086*f5c631daSSadaf Ebrahimi 
sqdecp(const Register & xdn,const PRegisterWithLaneSize & pg)2087*f5c631daSSadaf Ebrahimi void Assembler::sqdecp(const Register& xdn, const PRegisterWithLaneSize& pg) {
2088*f5c631daSSadaf Ebrahimi   // SQDECP <Xdn>, <Pg>.<T>
2089*f5c631daSSadaf Ebrahimi   //  0010 0101 ..10 1010 1000 110. .... ....
2090*f5c631daSSadaf Ebrahimi   //  size<23:22> | D<17> = 1 | U<16> = 0 | sf<10> = 1 | op<9> = 0 | Pg<8:5> |
2091*f5c631daSSadaf Ebrahimi   //  Rdn<4:0>
2092*f5c631daSSadaf Ebrahimi 
2093*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2094*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(xdn.IsX());
2095*f5c631daSSadaf Ebrahimi 
2096*f5c631daSSadaf Ebrahimi   Emit(SQDECP_r_p_r_x | SVESize(pg) | Rd(xdn) | Rx<8, 5>(pg));
2097*f5c631daSSadaf Ebrahimi }
2098*f5c631daSSadaf Ebrahimi 
sqdecp(const ZRegister & zdn,const PRegister & pg)2099*f5c631daSSadaf Ebrahimi void Assembler::sqdecp(const ZRegister& zdn, const PRegister& pg) {
2100*f5c631daSSadaf Ebrahimi   // SQDECP <Zdn>.<T>, <Pg>
2101*f5c631daSSadaf Ebrahimi   //  0010 0101 ..10 1010 1000 000. .... ....
2102*f5c631daSSadaf Ebrahimi   //  size<23:22> | D<17> = 1 | U<16> = 0 | opc<10:9> = 00 | Pg<8:5> | Zdn<4:0>
2103*f5c631daSSadaf Ebrahimi 
2104*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2105*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zdn.GetLaneSizeInBytes() != kBRegSizeInBytes);
2106*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pg.IsUnqualified());
2107*f5c631daSSadaf Ebrahimi 
2108*f5c631daSSadaf Ebrahimi   Emit(SQDECP_z_p_z | SVESize(zdn) | Rd(zdn) | Pg<8, 5>(pg));
2109*f5c631daSSadaf Ebrahimi }
2110*f5c631daSSadaf Ebrahimi 
sqincp(const Register & xd,const PRegisterWithLaneSize & pg,const Register & wn)2111*f5c631daSSadaf Ebrahimi void Assembler::sqincp(const Register& xd,
2112*f5c631daSSadaf Ebrahimi                        const PRegisterWithLaneSize& pg,
2113*f5c631daSSadaf Ebrahimi                        const Register& wn) {
2114*f5c631daSSadaf Ebrahimi   // SQINCP <Xdn>, <Pg>.<T>, <Wdn>
2115*f5c631daSSadaf Ebrahimi   //  0010 0101 ..10 1000 1000 100. .... ....
2116*f5c631daSSadaf Ebrahimi   //  size<23:22> | D<17> = 0 | U<16> = 0 | sf<10> = 0 | op<9> = 0 | Pg<8:5> |
2117*f5c631daSSadaf Ebrahimi   //  Rdn<4:0>
2118*f5c631daSSadaf Ebrahimi 
2119*f5c631daSSadaf Ebrahimi   USE(wn);
2120*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2121*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(xd.IsX() && wn.IsW() && xd.Aliases(wn));
2122*f5c631daSSadaf Ebrahimi 
2123*f5c631daSSadaf Ebrahimi   Emit(SQINCP_r_p_r_sx | SVESize(pg) | Rd(xd) | Rx<8, 5>(pg));
2124*f5c631daSSadaf Ebrahimi }
2125*f5c631daSSadaf Ebrahimi 
sqincp(const Register & xdn,const PRegisterWithLaneSize & pg)2126*f5c631daSSadaf Ebrahimi void Assembler::sqincp(const Register& xdn, const PRegisterWithLaneSize& pg) {
2127*f5c631daSSadaf Ebrahimi   // SQINCP <Xdn>, <Pg>.<T>
2128*f5c631daSSadaf Ebrahimi   //  0010 0101 ..10 1000 1000 110. .... ....
2129*f5c631daSSadaf Ebrahimi   //  size<23:22> | D<17> = 0 | U<16> = 0 | sf<10> = 1 | op<9> = 0 | Pg<8:5> |
2130*f5c631daSSadaf Ebrahimi   //  Rdn<4:0>
2131*f5c631daSSadaf Ebrahimi 
2132*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2133*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(xdn.IsX());
2134*f5c631daSSadaf Ebrahimi 
2135*f5c631daSSadaf Ebrahimi   Emit(SQINCP_r_p_r_x | SVESize(pg) | Rd(xdn) | Rx<8, 5>(pg));
2136*f5c631daSSadaf Ebrahimi }
2137*f5c631daSSadaf Ebrahimi 
sqincp(const ZRegister & zdn,const PRegister & pg)2138*f5c631daSSadaf Ebrahimi void Assembler::sqincp(const ZRegister& zdn, const PRegister& pg) {
2139*f5c631daSSadaf Ebrahimi   // SQINCP <Zdn>.<T>, <Pg>
2140*f5c631daSSadaf Ebrahimi   //  0010 0101 ..10 1000 1000 000. .... ....
2141*f5c631daSSadaf Ebrahimi   //  size<23:22> | D<17> = 0 | U<16> = 0 | opc<10:9> = 00 | Pg<8:5> | Zdn<4:0>
2142*f5c631daSSadaf Ebrahimi 
2143*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2144*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zdn.GetLaneSizeInBytes() != kBRegSizeInBytes);
2145*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pg.IsUnqualified());
2146*f5c631daSSadaf Ebrahimi 
2147*f5c631daSSadaf Ebrahimi   Emit(SQINCP_z_p_z | SVESize(zdn) | Rd(zdn) | Pg<8, 5>(pg));
2148*f5c631daSSadaf Ebrahimi }
2149*f5c631daSSadaf Ebrahimi 
uqdecp(const Register & rdn,const PRegisterWithLaneSize & pg)2150*f5c631daSSadaf Ebrahimi void Assembler::uqdecp(const Register& rdn, const PRegisterWithLaneSize& pg) {
2151*f5c631daSSadaf Ebrahimi   // UQDECP <Wdn>, <Pg>.<T>
2152*f5c631daSSadaf Ebrahimi   // UQDECP <Xdn>, <Pg>.<T>
2153*f5c631daSSadaf Ebrahimi   //  0010 0101 ..10 1011 1000 10.. .... ....
2154*f5c631daSSadaf Ebrahimi   //  size<23:22> | D<17> = 1 | U<16> = 1 | sf<10> | op<9> = 0 | Pg<8:5> |
2155*f5c631daSSadaf Ebrahimi   //  Rdn<4:0>
2156*f5c631daSSadaf Ebrahimi 
2157*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2158*f5c631daSSadaf Ebrahimi 
2159*f5c631daSSadaf Ebrahimi   Instr op = rdn.IsX() ? UQDECP_r_p_r_x : UQDECP_r_p_r_uw;
2160*f5c631daSSadaf Ebrahimi   Emit(op | SVESize(pg) | Rd(rdn) | Rx<8, 5>(pg));
2161*f5c631daSSadaf Ebrahimi }
2162*f5c631daSSadaf Ebrahimi 
uqdecp(const ZRegister & zdn,const PRegister & pg)2163*f5c631daSSadaf Ebrahimi void Assembler::uqdecp(const ZRegister& zdn, const PRegister& pg) {
2164*f5c631daSSadaf Ebrahimi   // UQDECP <Zdn>.<T>, <Pg>
2165*f5c631daSSadaf Ebrahimi   //  0010 0101 ..10 1011 1000 000. .... ....
2166*f5c631daSSadaf Ebrahimi   //  size<23:22> | D<17> = 1 | U<16> = 1 | opc<10:9> = 00 | Pg<8:5> | Zdn<4:0>
2167*f5c631daSSadaf Ebrahimi 
2168*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2169*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zdn.GetLaneSizeInBytes() != kBRegSizeInBytes);
2170*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pg.IsUnqualified());
2171*f5c631daSSadaf Ebrahimi 
2172*f5c631daSSadaf Ebrahimi   Emit(UQDECP_z_p_z | SVESize(zdn) | Rd(zdn) | Pg<8, 5>(pg));
2173*f5c631daSSadaf Ebrahimi }
2174*f5c631daSSadaf Ebrahimi 
uqincp(const Register & rdn,const PRegisterWithLaneSize & pg)2175*f5c631daSSadaf Ebrahimi void Assembler::uqincp(const Register& rdn, const PRegisterWithLaneSize& pg) {
2176*f5c631daSSadaf Ebrahimi   // UQINCP <Wdn>, <Pg>.<T>
2177*f5c631daSSadaf Ebrahimi   //  0010 0101 ..10 1001 1000 100. .... ....
2178*f5c631daSSadaf Ebrahimi   //  size<23:22> | D<17> = 0 | U<16> = 1 | sf<10> = 0 | op<9> = 0 | Pg<8:5> |
2179*f5c631daSSadaf Ebrahimi   //  Rdn<4:0>
2180*f5c631daSSadaf Ebrahimi 
2181*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2182*f5c631daSSadaf Ebrahimi 
2183*f5c631daSSadaf Ebrahimi   Instr op = rdn.IsX() ? UQINCP_r_p_r_x : UQINCP_r_p_r_uw;
2184*f5c631daSSadaf Ebrahimi   Emit(op | SVESize(pg) | Rd(rdn) | Rx<8, 5>(pg));
2185*f5c631daSSadaf Ebrahimi }
2186*f5c631daSSadaf Ebrahimi 
uqincp(const ZRegister & zdn,const PRegister & pg)2187*f5c631daSSadaf Ebrahimi void Assembler::uqincp(const ZRegister& zdn, const PRegister& pg) {
2188*f5c631daSSadaf Ebrahimi   // UQINCP <Zdn>.<T>, <Pg>
2189*f5c631daSSadaf Ebrahimi   //  0010 0101 ..10 1001 1000 000. .... ....
2190*f5c631daSSadaf Ebrahimi   //  size<23:22> | D<17> = 0 | U<16> = 1 | opc<10:9> = 00 | Pg<8:5> | Zdn<4:0>
2191*f5c631daSSadaf Ebrahimi 
2192*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2193*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zdn.GetLaneSizeInBytes() != kBRegSizeInBytes);
2194*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pg.IsUnqualified());
2195*f5c631daSSadaf Ebrahimi 
2196*f5c631daSSadaf Ebrahimi   Emit(UQINCP_z_p_z | SVESize(zdn) | Rd(zdn) | Pg<8, 5>(pg));
2197*f5c631daSSadaf Ebrahimi }
2198*f5c631daSSadaf Ebrahimi 
2199*f5c631daSSadaf Ebrahimi // SVEIndexGeneration.
2200*f5c631daSSadaf Ebrahimi 
index(const ZRegister & zd,int start,int step)2201*f5c631daSSadaf Ebrahimi void Assembler::index(const ZRegister& zd, int start, int step) {
2202*f5c631daSSadaf Ebrahimi   // INDEX <Zd>.<T>, #<imm1>, #<imm2>
2203*f5c631daSSadaf Ebrahimi   //  0000 0100 ..1. .... 0100 00.. .... ....
2204*f5c631daSSadaf Ebrahimi   //  size<23:22> | step<20:16> | start<9:5> | Zd<4:0>
2205*f5c631daSSadaf Ebrahimi 
2206*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2207*f5c631daSSadaf Ebrahimi 
2208*f5c631daSSadaf Ebrahimi   Emit(INDEX_z_ii | SVESize(zd) | ImmField<20, 16>(step) |
2209*f5c631daSSadaf Ebrahimi        ImmField<9, 5>(start) | Rd(zd));
2210*f5c631daSSadaf Ebrahimi }
2211*f5c631daSSadaf Ebrahimi 
index(const ZRegister & zd,const Register & rn,const Register & rm)2212*f5c631daSSadaf Ebrahimi void Assembler::index(const ZRegister& zd,
2213*f5c631daSSadaf Ebrahimi                       const Register& rn,
2214*f5c631daSSadaf Ebrahimi                       const Register& rm) {
2215*f5c631daSSadaf Ebrahimi   // INDEX <Zd>.<T>, <R><n>, <R><m>
2216*f5c631daSSadaf Ebrahimi   //  0000 0100 ..1. .... 0100 11.. .... ....
2217*f5c631daSSadaf Ebrahimi   //  size<23:22> | Rm<20:16> | Rn<9:5> | Zd<4:0>
2218*f5c631daSSadaf Ebrahimi 
2219*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2220*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(static_cast<unsigned>(rn.GetSizeInBits()) >=
2221*f5c631daSSadaf Ebrahimi               zd.GetLaneSizeInBits());
2222*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(static_cast<unsigned>(rm.GetSizeInBits()) >=
2223*f5c631daSSadaf Ebrahimi               zd.GetLaneSizeInBits());
2224*f5c631daSSadaf Ebrahimi 
2225*f5c631daSSadaf Ebrahimi   Emit(INDEX_z_rr | SVESize(zd) | Rd(zd) | Rn(rn) | Rm(rm));
2226*f5c631daSSadaf Ebrahimi }
2227*f5c631daSSadaf Ebrahimi 
index(const ZRegister & zd,const Register & rn,int imm5)2228*f5c631daSSadaf Ebrahimi void Assembler::index(const ZRegister& zd, const Register& rn, int imm5) {
2229*f5c631daSSadaf Ebrahimi   // INDEX <Zd>.<T>, <R><n>, #<imm>
2230*f5c631daSSadaf Ebrahimi   //  0000 0100 ..1. .... 0100 01.. .... ....
2231*f5c631daSSadaf Ebrahimi   //  size<23:22> | imm5<20:16> | Rn<9:5> | Zd<4:0>
2232*f5c631daSSadaf Ebrahimi 
2233*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2234*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(static_cast<unsigned>(rn.GetSizeInBits()) >=
2235*f5c631daSSadaf Ebrahimi               zd.GetLaneSizeInBits());
2236*f5c631daSSadaf Ebrahimi 
2237*f5c631daSSadaf Ebrahimi   Emit(INDEX_z_ri | SVESize(zd) | Rd(zd) | Rn(rn) | ImmField<20, 16>(imm5));
2238*f5c631daSSadaf Ebrahimi }
2239*f5c631daSSadaf Ebrahimi 
index(const ZRegister & zd,int imm5,const Register & rm)2240*f5c631daSSadaf Ebrahimi void Assembler::index(const ZRegister& zd, int imm5, const Register& rm) {
2241*f5c631daSSadaf Ebrahimi   // INDEX <Zd>.<T>, #<imm>, <R><m>
2242*f5c631daSSadaf Ebrahimi   //  0000 0100 ..1. .... 0100 10.. .... ....
2243*f5c631daSSadaf Ebrahimi   //  size<23:22> | Rm<20:16> | imm5<9:5> | Zd<4:0>
2244*f5c631daSSadaf Ebrahimi 
2245*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2246*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(static_cast<unsigned>(rm.GetSizeInBits()) >=
2247*f5c631daSSadaf Ebrahimi               zd.GetLaneSizeInBits());
2248*f5c631daSSadaf Ebrahimi 
2249*f5c631daSSadaf Ebrahimi   Emit(INDEX_z_ir | SVESize(zd) | Rd(zd) | ImmField<9, 5>(imm5) | Rm(rm));
2250*f5c631daSSadaf Ebrahimi }
2251*f5c631daSSadaf Ebrahimi 
2252*f5c631daSSadaf Ebrahimi // SVEIntArithmeticUnpredicated.
2253*f5c631daSSadaf Ebrahimi 
add(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)2254*f5c631daSSadaf Ebrahimi void Assembler::add(const ZRegister& zd,
2255*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
2256*f5c631daSSadaf Ebrahimi                     const ZRegister& zm) {
2257*f5c631daSSadaf Ebrahimi   // ADD <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
2258*f5c631daSSadaf Ebrahimi   //  0000 0100 ..1. .... 0000 00.. .... ....
2259*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<12:10> = 000 | Zn<9:5> | Zd<4:0>
2260*f5c631daSSadaf Ebrahimi 
2261*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2262*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
2263*f5c631daSSadaf Ebrahimi 
2264*f5c631daSSadaf Ebrahimi   Emit(ADD_z_zz | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
2265*f5c631daSSadaf Ebrahimi }
2266*f5c631daSSadaf Ebrahimi 
sqadd(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)2267*f5c631daSSadaf Ebrahimi void Assembler::sqadd(const ZRegister& zd,
2268*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
2269*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
2270*f5c631daSSadaf Ebrahimi   // SQADD <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
2271*f5c631daSSadaf Ebrahimi   //  0000 0100 ..1. .... 0001 00.. .... ....
2272*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<12:10> = 100 | Zn<9:5> | Zd<4:0>
2273*f5c631daSSadaf Ebrahimi 
2274*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2275*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
2276*f5c631daSSadaf Ebrahimi 
2277*f5c631daSSadaf Ebrahimi   Emit(SQADD_z_zz | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
2278*f5c631daSSadaf Ebrahimi }
2279*f5c631daSSadaf Ebrahimi 
sqsub(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)2280*f5c631daSSadaf Ebrahimi void Assembler::sqsub(const ZRegister& zd,
2281*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
2282*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
2283*f5c631daSSadaf Ebrahimi   // SQSUB <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
2284*f5c631daSSadaf Ebrahimi   //  0000 0100 ..1. .... 0001 10.. .... ....
2285*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<12:10> = 110 | Zn<9:5> | Zd<4:0>
2286*f5c631daSSadaf Ebrahimi 
2287*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2288*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
2289*f5c631daSSadaf Ebrahimi 
2290*f5c631daSSadaf Ebrahimi   Emit(SQSUB_z_zz | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
2291*f5c631daSSadaf Ebrahimi }
2292*f5c631daSSadaf Ebrahimi 
sub(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)2293*f5c631daSSadaf Ebrahimi void Assembler::sub(const ZRegister& zd,
2294*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
2295*f5c631daSSadaf Ebrahimi                     const ZRegister& zm) {
2296*f5c631daSSadaf Ebrahimi   // SUB <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
2297*f5c631daSSadaf Ebrahimi   //  0000 0100 ..1. .... 0000 01.. .... ....
2298*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<12:10> = 001 | Zn<9:5> | Zd<4:0>
2299*f5c631daSSadaf Ebrahimi 
2300*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2301*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
2302*f5c631daSSadaf Ebrahimi 
2303*f5c631daSSadaf Ebrahimi   Emit(SUB_z_zz | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
2304*f5c631daSSadaf Ebrahimi }
2305*f5c631daSSadaf Ebrahimi 
uqadd(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)2306*f5c631daSSadaf Ebrahimi void Assembler::uqadd(const ZRegister& zd,
2307*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
2308*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
2309*f5c631daSSadaf Ebrahimi   // UQADD <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
2310*f5c631daSSadaf Ebrahimi   //  0000 0100 ..1. .... 0001 01.. .... ....
2311*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<12:10> = 101 | Zn<9:5> | Zd<4:0>
2312*f5c631daSSadaf Ebrahimi 
2313*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2314*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
2315*f5c631daSSadaf Ebrahimi 
2316*f5c631daSSadaf Ebrahimi   Emit(UQADD_z_zz | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
2317*f5c631daSSadaf Ebrahimi }
2318*f5c631daSSadaf Ebrahimi 
uqsub(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)2319*f5c631daSSadaf Ebrahimi void Assembler::uqsub(const ZRegister& zd,
2320*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
2321*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
2322*f5c631daSSadaf Ebrahimi   // UQSUB <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
2323*f5c631daSSadaf Ebrahimi   //  0000 0100 ..1. .... 0001 11.. .... ....
2324*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<12:10> = 111 | Zn<9:5> | Zd<4:0>
2325*f5c631daSSadaf Ebrahimi 
2326*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2327*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
2328*f5c631daSSadaf Ebrahimi 
2329*f5c631daSSadaf Ebrahimi   Emit(UQSUB_z_zz | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
2330*f5c631daSSadaf Ebrahimi }
2331*f5c631daSSadaf Ebrahimi 
2332*f5c631daSSadaf Ebrahimi // SVEIntBinaryArithmeticPredicated.
2333*f5c631daSSadaf Ebrahimi 
add(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)2334*f5c631daSSadaf Ebrahimi void Assembler::add(const ZRegister& zd,
2335*f5c631daSSadaf Ebrahimi                     const PRegisterM& pg,
2336*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
2337*f5c631daSSadaf Ebrahimi                     const ZRegister& zm) {
2338*f5c631daSSadaf Ebrahimi   // ADD <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
2339*f5c631daSSadaf Ebrahimi   //  0000 0100 ..00 0000 000. .... .... ....
2340*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 000 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
2341*f5c631daSSadaf Ebrahimi 
2342*f5c631daSSadaf Ebrahimi   USE(zn);
2343*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2344*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
2345*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(zd, zn, zm));
2346*f5c631daSSadaf Ebrahimi 
2347*f5c631daSSadaf Ebrahimi   Emit(ADD_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
2348*f5c631daSSadaf Ebrahimi }
2349*f5c631daSSadaf Ebrahimi 
and_(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)2350*f5c631daSSadaf Ebrahimi void Assembler::and_(const ZRegister& zd,
2351*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
2352*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
2353*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
2354*f5c631daSSadaf Ebrahimi   // AND <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
2355*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 1010 000. .... .... ....
2356*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 010 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
2357*f5c631daSSadaf Ebrahimi 
2358*f5c631daSSadaf Ebrahimi   USE(zn);
2359*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2360*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
2361*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(zd, zn, zm));
2362*f5c631daSSadaf Ebrahimi 
2363*f5c631daSSadaf Ebrahimi   Emit(AND_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
2364*f5c631daSSadaf Ebrahimi }
2365*f5c631daSSadaf Ebrahimi 
bic(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)2366*f5c631daSSadaf Ebrahimi void Assembler::bic(const ZRegister& zd,
2367*f5c631daSSadaf Ebrahimi                     const PRegisterM& pg,
2368*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
2369*f5c631daSSadaf Ebrahimi                     const ZRegister& zm) {
2370*f5c631daSSadaf Ebrahimi   // BIC <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
2371*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 1011 000. .... .... ....
2372*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 011 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
2373*f5c631daSSadaf Ebrahimi 
2374*f5c631daSSadaf Ebrahimi   USE(zn);
2375*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2376*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
2377*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(zd, zn, zm));
2378*f5c631daSSadaf Ebrahimi 
2379*f5c631daSSadaf Ebrahimi   Emit(BIC_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
2380*f5c631daSSadaf Ebrahimi }
2381*f5c631daSSadaf Ebrahimi 
eor(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)2382*f5c631daSSadaf Ebrahimi void Assembler::eor(const ZRegister& zd,
2383*f5c631daSSadaf Ebrahimi                     const PRegisterM& pg,
2384*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
2385*f5c631daSSadaf Ebrahimi                     const ZRegister& zm) {
2386*f5c631daSSadaf Ebrahimi   // EOR <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
2387*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 1001 000. .... .... ....
2388*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 001 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
2389*f5c631daSSadaf Ebrahimi 
2390*f5c631daSSadaf Ebrahimi   USE(zn);
2391*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2392*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
2393*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(zd, zn, zm));
2394*f5c631daSSadaf Ebrahimi 
2395*f5c631daSSadaf Ebrahimi   Emit(EOR_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
2396*f5c631daSSadaf Ebrahimi }
2397*f5c631daSSadaf Ebrahimi 
mul(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)2398*f5c631daSSadaf Ebrahimi void Assembler::mul(const ZRegister& zd,
2399*f5c631daSSadaf Ebrahimi                     const PRegisterM& pg,
2400*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
2401*f5c631daSSadaf Ebrahimi                     const ZRegister& zm) {
2402*f5c631daSSadaf Ebrahimi   // MUL <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
2403*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 0000 000. .... .... ....
2404*f5c631daSSadaf Ebrahimi   //  size<23:22> | H<17> = 0 | U<16> = 0 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
2405*f5c631daSSadaf Ebrahimi 
2406*f5c631daSSadaf Ebrahimi   USE(zn);
2407*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2408*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
2409*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(zd, zn, zm));
2410*f5c631daSSadaf Ebrahimi 
2411*f5c631daSSadaf Ebrahimi   Emit(MUL_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
2412*f5c631daSSadaf Ebrahimi }
2413*f5c631daSSadaf Ebrahimi 
orr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)2414*f5c631daSSadaf Ebrahimi void Assembler::orr(const ZRegister& zd,
2415*f5c631daSSadaf Ebrahimi                     const PRegisterM& pg,
2416*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
2417*f5c631daSSadaf Ebrahimi                     const ZRegister& zm) {
2418*f5c631daSSadaf Ebrahimi   // ORR <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
2419*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 1000 000. .... .... ....
2420*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 000 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
2421*f5c631daSSadaf Ebrahimi 
2422*f5c631daSSadaf Ebrahimi   USE(zn);
2423*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2424*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
2425*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(zd, zn, zm));
2426*f5c631daSSadaf Ebrahimi 
2427*f5c631daSSadaf Ebrahimi   Emit(ORR_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
2428*f5c631daSSadaf Ebrahimi }
2429*f5c631daSSadaf Ebrahimi 
sabd(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)2430*f5c631daSSadaf Ebrahimi void Assembler::sabd(const ZRegister& zd,
2431*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
2432*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
2433*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
2434*f5c631daSSadaf Ebrahimi   // SABD <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
2435*f5c631daSSadaf Ebrahimi   //  0000 0100 ..00 1100 000. .... .... ....
2436*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:17> = 10 | U<16> = 0 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
2437*f5c631daSSadaf Ebrahimi 
2438*f5c631daSSadaf Ebrahimi   USE(zn);
2439*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2440*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
2441*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(zd, zn, zm));
2442*f5c631daSSadaf Ebrahimi 
2443*f5c631daSSadaf Ebrahimi   Emit(SABD_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
2444*f5c631daSSadaf Ebrahimi }
2445*f5c631daSSadaf Ebrahimi 
sdiv(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)2446*f5c631daSSadaf Ebrahimi void Assembler::sdiv(const ZRegister& zd,
2447*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
2448*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
2449*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
2450*f5c631daSSadaf Ebrahimi   // SDIV <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
2451*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 0100 000. .... .... ....
2452*f5c631daSSadaf Ebrahimi   //  size<23:22> | R<17> = 0 | U<16> = 0 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
2453*f5c631daSSadaf Ebrahimi 
2454*f5c631daSSadaf Ebrahimi   USE(zn);
2455*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2456*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
2457*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(zd, zn, zm));
2458*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeS() || zd.IsLaneSizeD());
2459*f5c631daSSadaf Ebrahimi 
2460*f5c631daSSadaf Ebrahimi   Emit(SDIV_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
2461*f5c631daSSadaf Ebrahimi }
2462*f5c631daSSadaf Ebrahimi 
sdivr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)2463*f5c631daSSadaf Ebrahimi void Assembler::sdivr(const ZRegister& zd,
2464*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
2465*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
2466*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
2467*f5c631daSSadaf Ebrahimi   // SDIVR <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
2468*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 0110 000. .... .... ....
2469*f5c631daSSadaf Ebrahimi   //  size<23:22> | R<17> = 1 | U<16> = 0 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
2470*f5c631daSSadaf Ebrahimi 
2471*f5c631daSSadaf Ebrahimi   USE(zn);
2472*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2473*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
2474*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(zd, zn, zm));
2475*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeS() || zd.IsLaneSizeD());
2476*f5c631daSSadaf Ebrahimi 
2477*f5c631daSSadaf Ebrahimi   Emit(SDIVR_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
2478*f5c631daSSadaf Ebrahimi }
2479*f5c631daSSadaf Ebrahimi 
smax(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)2480*f5c631daSSadaf Ebrahimi void Assembler::smax(const ZRegister& zd,
2481*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
2482*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
2483*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
2484*f5c631daSSadaf Ebrahimi   // SMAX <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
2485*f5c631daSSadaf Ebrahimi   //  0000 0100 ..00 1000 000. .... .... ....
2486*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:17> = 00 | U<16> = 0 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
2487*f5c631daSSadaf Ebrahimi 
2488*f5c631daSSadaf Ebrahimi   USE(zn);
2489*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2490*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
2491*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(zd, zn, zm));
2492*f5c631daSSadaf Ebrahimi 
2493*f5c631daSSadaf Ebrahimi   Emit(SMAX_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
2494*f5c631daSSadaf Ebrahimi }
2495*f5c631daSSadaf Ebrahimi 
smin(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)2496*f5c631daSSadaf Ebrahimi void Assembler::smin(const ZRegister& zd,
2497*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
2498*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
2499*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
2500*f5c631daSSadaf Ebrahimi   // SMIN <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
2501*f5c631daSSadaf Ebrahimi   //  0000 0100 ..00 1010 000. .... .... ....
2502*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:17> = 01 | U<16> = 0 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
2503*f5c631daSSadaf Ebrahimi 
2504*f5c631daSSadaf Ebrahimi   USE(zn);
2505*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2506*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
2507*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(zd, zn, zm));
2508*f5c631daSSadaf Ebrahimi 
2509*f5c631daSSadaf Ebrahimi   Emit(SMIN_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
2510*f5c631daSSadaf Ebrahimi }
2511*f5c631daSSadaf Ebrahimi 
smulh(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)2512*f5c631daSSadaf Ebrahimi void Assembler::smulh(const ZRegister& zd,
2513*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
2514*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
2515*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
2516*f5c631daSSadaf Ebrahimi   // SMULH <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
2517*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 0010 000. .... .... ....
2518*f5c631daSSadaf Ebrahimi   //  size<23:22> | H<17> = 1 | U<16> = 0 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
2519*f5c631daSSadaf Ebrahimi 
2520*f5c631daSSadaf Ebrahimi   USE(zn);
2521*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2522*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
2523*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(zd, zn, zm));
2524*f5c631daSSadaf Ebrahimi 
2525*f5c631daSSadaf Ebrahimi   Emit(SMULH_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
2526*f5c631daSSadaf Ebrahimi }
2527*f5c631daSSadaf Ebrahimi 
sub(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)2528*f5c631daSSadaf Ebrahimi void Assembler::sub(const ZRegister& zd,
2529*f5c631daSSadaf Ebrahimi                     const PRegisterM& pg,
2530*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
2531*f5c631daSSadaf Ebrahimi                     const ZRegister& zm) {
2532*f5c631daSSadaf Ebrahimi   // SUB <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
2533*f5c631daSSadaf Ebrahimi   //  0000 0100 ..00 0001 000. .... .... ....
2534*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 001 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
2535*f5c631daSSadaf Ebrahimi 
2536*f5c631daSSadaf Ebrahimi   USE(zn);
2537*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2538*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
2539*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(zd, zn, zm));
2540*f5c631daSSadaf Ebrahimi 
2541*f5c631daSSadaf Ebrahimi   Emit(SUB_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
2542*f5c631daSSadaf Ebrahimi }
2543*f5c631daSSadaf Ebrahimi 
subr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)2544*f5c631daSSadaf Ebrahimi void Assembler::subr(const ZRegister& zd,
2545*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
2546*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
2547*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
2548*f5c631daSSadaf Ebrahimi   // SUBR <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
2549*f5c631daSSadaf Ebrahimi   //  0000 0100 ..00 0011 000. .... .... ....
2550*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 011 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
2551*f5c631daSSadaf Ebrahimi 
2552*f5c631daSSadaf Ebrahimi   USE(zn);
2553*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2554*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
2555*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(zd, zn, zm));
2556*f5c631daSSadaf Ebrahimi 
2557*f5c631daSSadaf Ebrahimi   Emit(SUBR_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
2558*f5c631daSSadaf Ebrahimi }
2559*f5c631daSSadaf Ebrahimi 
uabd(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)2560*f5c631daSSadaf Ebrahimi void Assembler::uabd(const ZRegister& zd,
2561*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
2562*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
2563*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
2564*f5c631daSSadaf Ebrahimi   // UABD <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
2565*f5c631daSSadaf Ebrahimi   //  0000 0100 ..00 1101 000. .... .... ....
2566*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:17> = 10 | U<16> = 1 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
2567*f5c631daSSadaf Ebrahimi 
2568*f5c631daSSadaf Ebrahimi   USE(zn);
2569*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2570*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
2571*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(zd, zn, zm));
2572*f5c631daSSadaf Ebrahimi 
2573*f5c631daSSadaf Ebrahimi   Emit(UABD_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
2574*f5c631daSSadaf Ebrahimi }
2575*f5c631daSSadaf Ebrahimi 
udiv(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)2576*f5c631daSSadaf Ebrahimi void Assembler::udiv(const ZRegister& zd,
2577*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
2578*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
2579*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
2580*f5c631daSSadaf Ebrahimi   // UDIV <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
2581*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 0101 000. .... .... ....
2582*f5c631daSSadaf Ebrahimi   //  size<23:22> | R<17> = 0 | U<16> = 1 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
2583*f5c631daSSadaf Ebrahimi 
2584*f5c631daSSadaf Ebrahimi   USE(zn);
2585*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2586*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
2587*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(zd, zn, zm));
2588*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeS() || zd.IsLaneSizeD());
2589*f5c631daSSadaf Ebrahimi 
2590*f5c631daSSadaf Ebrahimi   Emit(UDIV_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
2591*f5c631daSSadaf Ebrahimi }
2592*f5c631daSSadaf Ebrahimi 
udivr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)2593*f5c631daSSadaf Ebrahimi void Assembler::udivr(const ZRegister& zd,
2594*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
2595*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
2596*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
2597*f5c631daSSadaf Ebrahimi   // UDIVR <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
2598*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 0111 000. .... .... ....
2599*f5c631daSSadaf Ebrahimi   //  size<23:22> | R<17> = 1 | U<16> = 1 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
2600*f5c631daSSadaf Ebrahimi 
2601*f5c631daSSadaf Ebrahimi   USE(zn);
2602*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2603*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
2604*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(zd, zn, zm));
2605*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeS() || zd.IsLaneSizeD());
2606*f5c631daSSadaf Ebrahimi 
2607*f5c631daSSadaf Ebrahimi   Emit(UDIVR_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
2608*f5c631daSSadaf Ebrahimi }
2609*f5c631daSSadaf Ebrahimi 
umax(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)2610*f5c631daSSadaf Ebrahimi void Assembler::umax(const ZRegister& zd,
2611*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
2612*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
2613*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
2614*f5c631daSSadaf Ebrahimi   // UMAX <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
2615*f5c631daSSadaf Ebrahimi   //  0000 0100 ..00 1001 000. .... .... ....
2616*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:17> = 00 | U<16> = 1 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
2617*f5c631daSSadaf Ebrahimi 
2618*f5c631daSSadaf Ebrahimi   USE(zn);
2619*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2620*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
2621*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(zd, zn, zm));
2622*f5c631daSSadaf Ebrahimi 
2623*f5c631daSSadaf Ebrahimi   Emit(UMAX_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
2624*f5c631daSSadaf Ebrahimi }
2625*f5c631daSSadaf Ebrahimi 
umin(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)2626*f5c631daSSadaf Ebrahimi void Assembler::umin(const ZRegister& zd,
2627*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
2628*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
2629*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
2630*f5c631daSSadaf Ebrahimi   // UMIN <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
2631*f5c631daSSadaf Ebrahimi   //  0000 0100 ..00 1011 000. .... .... ....
2632*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:17> = 01 | U<16> = 1 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
2633*f5c631daSSadaf Ebrahimi 
2634*f5c631daSSadaf Ebrahimi   USE(zn);
2635*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2636*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
2637*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(zd, zn, zm));
2638*f5c631daSSadaf Ebrahimi 
2639*f5c631daSSadaf Ebrahimi   Emit(UMIN_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
2640*f5c631daSSadaf Ebrahimi }
2641*f5c631daSSadaf Ebrahimi 
umulh(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)2642*f5c631daSSadaf Ebrahimi void Assembler::umulh(const ZRegister& zd,
2643*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
2644*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
2645*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
2646*f5c631daSSadaf Ebrahimi   // UMULH <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
2647*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 0011 000. .... .... ....
2648*f5c631daSSadaf Ebrahimi   //  size<23:22> | H<17> = 1 | U<16> = 1 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
2649*f5c631daSSadaf Ebrahimi 
2650*f5c631daSSadaf Ebrahimi   USE(zn);
2651*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2652*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
2653*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(zd, zn, zm));
2654*f5c631daSSadaf Ebrahimi 
2655*f5c631daSSadaf Ebrahimi   Emit(UMULH_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
2656*f5c631daSSadaf Ebrahimi }
2657*f5c631daSSadaf Ebrahimi 
2658*f5c631daSSadaf Ebrahimi // SVEIntCompareScalars.
2659*f5c631daSSadaf Ebrahimi 
ctermeq(const Register & rn,const Register & rm)2660*f5c631daSSadaf Ebrahimi void Assembler::ctermeq(const Register& rn, const Register& rm) {
2661*f5c631daSSadaf Ebrahimi   // CTERMEQ <R><n>, <R><m>
2662*f5c631daSSadaf Ebrahimi   //  0010 0101 1.1. .... 0010 00.. ...0 0000
2663*f5c631daSSadaf Ebrahimi   //  op<23> = 1 | sz<22> | Rm<20:16> | Rn<9:5> | ne<4> = 0
2664*f5c631daSSadaf Ebrahimi 
2665*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2666*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameSizeAndType(rn, rm));
2667*f5c631daSSadaf Ebrahimi   const Instr sz = rn.Is64Bits() ? 0x00400000 : 0x00000000;
2668*f5c631daSSadaf Ebrahimi 
2669*f5c631daSSadaf Ebrahimi   Emit(CTERMEQ_rr | sz | Rn(rn) | Rm(rm));
2670*f5c631daSSadaf Ebrahimi }
2671*f5c631daSSadaf Ebrahimi 
ctermne(const Register & rn,const Register & rm)2672*f5c631daSSadaf Ebrahimi void Assembler::ctermne(const Register& rn, const Register& rm) {
2673*f5c631daSSadaf Ebrahimi   // CTERMNE <R><n>, <R><m>
2674*f5c631daSSadaf Ebrahimi   //  0010 0101 1.1. .... 0010 00.. ...1 0000
2675*f5c631daSSadaf Ebrahimi   //  op<23> = 1 | sz<22> | Rm<20:16> | Rn<9:5> | ne<4> = 1
2676*f5c631daSSadaf Ebrahimi 
2677*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2678*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameSizeAndType(rn, rm));
2679*f5c631daSSadaf Ebrahimi   const Instr sz = rn.Is64Bits() ? 0x00400000 : 0x00000000;
2680*f5c631daSSadaf Ebrahimi 
2681*f5c631daSSadaf Ebrahimi   Emit(CTERMNE_rr | sz | Rn(rn) | Rm(rm));
2682*f5c631daSSadaf Ebrahimi }
2683*f5c631daSSadaf Ebrahimi 
whilele(const PRegisterWithLaneSize & pd,const Register & rn,const Register & rm)2684*f5c631daSSadaf Ebrahimi void Assembler::whilele(const PRegisterWithLaneSize& pd,
2685*f5c631daSSadaf Ebrahimi                         const Register& rn,
2686*f5c631daSSadaf Ebrahimi                         const Register& rm) {
2687*f5c631daSSadaf Ebrahimi   // WHILELE <Pd>.<T>, <R><n>, <R><m>
2688*f5c631daSSadaf Ebrahimi   //  0010 0101 ..1. .... 000. 01.. ...1 ....
2689*f5c631daSSadaf Ebrahimi   //  size<23:22> | Rm<20:16> | sf<12> | U<11> = 0 | lt<10> = 1 | Rn<9:5> |
2690*f5c631daSSadaf Ebrahimi   //  eq<4> = 1 | Pd<3:0>
2691*f5c631daSSadaf Ebrahimi 
2692*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2693*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameSizeAndType(rn, rm));
2694*f5c631daSSadaf Ebrahimi   const Instr sf = rn.Is64Bits() ? 0x00001000 : 0x00000000;
2695*f5c631daSSadaf Ebrahimi 
2696*f5c631daSSadaf Ebrahimi   Emit(WHILELE_p_p_rr | SVESize(pd) | sf | Pd(pd) | Rn(rn) | Rm(rm));
2697*f5c631daSSadaf Ebrahimi }
2698*f5c631daSSadaf Ebrahimi 
whilelo(const PRegisterWithLaneSize & pd,const Register & rn,const Register & rm)2699*f5c631daSSadaf Ebrahimi void Assembler::whilelo(const PRegisterWithLaneSize& pd,
2700*f5c631daSSadaf Ebrahimi                         const Register& rn,
2701*f5c631daSSadaf Ebrahimi                         const Register& rm) {
2702*f5c631daSSadaf Ebrahimi   // WHILELO <Pd>.<T>, <R><n>, <R><m>
2703*f5c631daSSadaf Ebrahimi   //  0010 0101 ..1. .... 000. 11.. ...0 ....
2704*f5c631daSSadaf Ebrahimi   //  size<23:22> | Rm<20:16> | sf<12> | U<11> = 1 | lt<10> = 1 | Rn<9:5> |
2705*f5c631daSSadaf Ebrahimi   //  eq<4> = 0 | Pd<3:0>
2706*f5c631daSSadaf Ebrahimi 
2707*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2708*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameSizeAndType(rn, rm));
2709*f5c631daSSadaf Ebrahimi   const Instr sf = rn.Is64Bits() ? 0x00001000 : 0x00000000;
2710*f5c631daSSadaf Ebrahimi 
2711*f5c631daSSadaf Ebrahimi   Emit(WHILELO_p_p_rr | SVESize(pd) | sf | Pd(pd) | Rn(rn) | Rm(rm));
2712*f5c631daSSadaf Ebrahimi }
2713*f5c631daSSadaf Ebrahimi 
whilels(const PRegisterWithLaneSize & pd,const Register & rn,const Register & rm)2714*f5c631daSSadaf Ebrahimi void Assembler::whilels(const PRegisterWithLaneSize& pd,
2715*f5c631daSSadaf Ebrahimi                         const Register& rn,
2716*f5c631daSSadaf Ebrahimi                         const Register& rm) {
2717*f5c631daSSadaf Ebrahimi   // WHILELS <Pd>.<T>, <R><n>, <R><m>
2718*f5c631daSSadaf Ebrahimi   //  0010 0101 ..1. .... 000. 11.. ...1 ....
2719*f5c631daSSadaf Ebrahimi   //  size<23:22> | Rm<20:16> | sf<12> | U<11> = 1 | lt<10> = 1 | Rn<9:5> |
2720*f5c631daSSadaf Ebrahimi   //  eq<4> = 1 | Pd<3:0>
2721*f5c631daSSadaf Ebrahimi 
2722*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2723*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameSizeAndType(rn, rm));
2724*f5c631daSSadaf Ebrahimi   const Instr sf = rn.Is64Bits() ? 0x00001000 : 0x00000000;
2725*f5c631daSSadaf Ebrahimi 
2726*f5c631daSSadaf Ebrahimi   Emit(WHILELS_p_p_rr | SVESize(pd) | sf | Pd(pd) | Rn(rn) | Rm(rm));
2727*f5c631daSSadaf Ebrahimi }
2728*f5c631daSSadaf Ebrahimi 
whilelt(const PRegisterWithLaneSize & pd,const Register & rn,const Register & rm)2729*f5c631daSSadaf Ebrahimi void Assembler::whilelt(const PRegisterWithLaneSize& pd,
2730*f5c631daSSadaf Ebrahimi                         const Register& rn,
2731*f5c631daSSadaf Ebrahimi                         const Register& rm) {
2732*f5c631daSSadaf Ebrahimi   // WHILELT <Pd>.<T>, <R><n>, <R><m>
2733*f5c631daSSadaf Ebrahimi   //  0010 0101 ..1. .... 000. 01.. ...0 ....
2734*f5c631daSSadaf Ebrahimi   //  size<23:22> | Rm<20:16> | sf<12> | U<11> = 0 | lt<10> = 1 | Rn<9:5> |
2735*f5c631daSSadaf Ebrahimi   //  eq<4> = 0 | Pd<3:0>
2736*f5c631daSSadaf Ebrahimi 
2737*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2738*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameSizeAndType(rn, rm));
2739*f5c631daSSadaf Ebrahimi   const Instr sf = rn.Is64Bits() ? 0x00001000 : 0x00000000;
2740*f5c631daSSadaf Ebrahimi 
2741*f5c631daSSadaf Ebrahimi   Emit(WHILELT_p_p_rr | SVESize(pd) | sf | Pd(pd) | Rn(rn) | Rm(rm));
2742*f5c631daSSadaf Ebrahimi }
2743*f5c631daSSadaf Ebrahimi 
CompareVectors(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm,SVEIntCompareVectorsOp op)2744*f5c631daSSadaf Ebrahimi void Assembler::CompareVectors(const PRegisterWithLaneSize& pd,
2745*f5c631daSSadaf Ebrahimi                                const PRegisterZ& pg,
2746*f5c631daSSadaf Ebrahimi                                const ZRegister& zn,
2747*f5c631daSSadaf Ebrahimi                                const ZRegister& zm,
2748*f5c631daSSadaf Ebrahimi                                SVEIntCompareVectorsOp op) {
2749*f5c631daSSadaf Ebrahimi   Emit(op | SVESize(zn) | Pd(pd) | PgLow8(pg) | Rn(zn) | Rm(zm));
2750*f5c631daSSadaf Ebrahimi }
2751*f5c631daSSadaf Ebrahimi 
CompareVectors(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,int imm,SVEIntCompareSignedImmOp op)2752*f5c631daSSadaf Ebrahimi void Assembler::CompareVectors(const PRegisterWithLaneSize& pd,
2753*f5c631daSSadaf Ebrahimi                                const PRegisterZ& pg,
2754*f5c631daSSadaf Ebrahimi                                const ZRegister& zn,
2755*f5c631daSSadaf Ebrahimi                                int imm,
2756*f5c631daSSadaf Ebrahimi                                SVEIntCompareSignedImmOp op) {
2757*f5c631daSSadaf Ebrahimi   Emit(op | SVESize(zn) | Pd(pd) | PgLow8(pg) | Rn(zn) | ImmField<20, 16>(imm));
2758*f5c631daSSadaf Ebrahimi }
2759*f5c631daSSadaf Ebrahimi 
CompareVectors(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,unsigned imm,SVEIntCompareUnsignedImmOp op)2760*f5c631daSSadaf Ebrahimi void Assembler::CompareVectors(const PRegisterWithLaneSize& pd,
2761*f5c631daSSadaf Ebrahimi                                const PRegisterZ& pg,
2762*f5c631daSSadaf Ebrahimi                                const ZRegister& zn,
2763*f5c631daSSadaf Ebrahimi                                unsigned imm,
2764*f5c631daSSadaf Ebrahimi                                SVEIntCompareUnsignedImmOp op) {
2765*f5c631daSSadaf Ebrahimi   Emit(op | SVESize(zn) | Pd(pd) | PgLow8(pg) | Rn(zn) |
2766*f5c631daSSadaf Ebrahimi        ImmUnsignedField<20, 14>(imm));
2767*f5c631daSSadaf Ebrahimi }
2768*f5c631daSSadaf Ebrahimi 
cmp(Condition cond,const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)2769*f5c631daSSadaf Ebrahimi void Assembler::cmp(Condition cond,
2770*f5c631daSSadaf Ebrahimi                     const PRegisterWithLaneSize& pd,
2771*f5c631daSSadaf Ebrahimi                     const PRegisterZ& pg,
2772*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
2773*f5c631daSSadaf Ebrahimi                     const ZRegister& zm) {
2774*f5c631daSSadaf Ebrahimi   switch (cond) {
2775*f5c631daSSadaf Ebrahimi     case eq:
2776*f5c631daSSadaf Ebrahimi       cmpeq(pd, pg, zn, zm);
2777*f5c631daSSadaf Ebrahimi       break;
2778*f5c631daSSadaf Ebrahimi     case ge:
2779*f5c631daSSadaf Ebrahimi       cmpge(pd, pg, zn, zm);
2780*f5c631daSSadaf Ebrahimi       break;
2781*f5c631daSSadaf Ebrahimi     case gt:
2782*f5c631daSSadaf Ebrahimi       cmpgt(pd, pg, zn, zm);
2783*f5c631daSSadaf Ebrahimi       break;
2784*f5c631daSSadaf Ebrahimi     case le:
2785*f5c631daSSadaf Ebrahimi       cmple(pd, pg, zn, zm);
2786*f5c631daSSadaf Ebrahimi       break;
2787*f5c631daSSadaf Ebrahimi     case lt:
2788*f5c631daSSadaf Ebrahimi       cmplt(pd, pg, zn, zm);
2789*f5c631daSSadaf Ebrahimi       break;
2790*f5c631daSSadaf Ebrahimi     case ne:
2791*f5c631daSSadaf Ebrahimi       cmpne(pd, pg, zn, zm);
2792*f5c631daSSadaf Ebrahimi       break;
2793*f5c631daSSadaf Ebrahimi     case hi:
2794*f5c631daSSadaf Ebrahimi       cmphi(pd, pg, zn, zm);
2795*f5c631daSSadaf Ebrahimi       break;
2796*f5c631daSSadaf Ebrahimi     case hs:
2797*f5c631daSSadaf Ebrahimi       cmphs(pd, pg, zn, zm);
2798*f5c631daSSadaf Ebrahimi       break;
2799*f5c631daSSadaf Ebrahimi     case lo:
2800*f5c631daSSadaf Ebrahimi       cmplo(pd, pg, zn, zm);
2801*f5c631daSSadaf Ebrahimi       break;
2802*f5c631daSSadaf Ebrahimi     case ls:
2803*f5c631daSSadaf Ebrahimi       cmpls(pd, pg, zn, zm);
2804*f5c631daSSadaf Ebrahimi       break;
2805*f5c631daSSadaf Ebrahimi     default:
2806*f5c631daSSadaf Ebrahimi       VIXL_UNREACHABLE();
2807*f5c631daSSadaf Ebrahimi   }
2808*f5c631daSSadaf Ebrahimi }
2809*f5c631daSSadaf Ebrahimi 
2810*f5c631daSSadaf Ebrahimi // SVEIntCompareSignedImm.
2811*f5c631daSSadaf Ebrahimi 
cmpeq(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,int imm5)2812*f5c631daSSadaf Ebrahimi void Assembler::cmpeq(const PRegisterWithLaneSize& pd,
2813*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
2814*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
2815*f5c631daSSadaf Ebrahimi                       int imm5) {
2816*f5c631daSSadaf Ebrahimi   // CMPEQ <Pd>.<T>, <Pg>/Z, <Zn>.<T>, #<imm>
2817*f5c631daSSadaf Ebrahimi   //  0010 0101 ..0. .... 100. .... ...0 ....
2818*f5c631daSSadaf Ebrahimi   //  size<23:22> | imm5<20:16> | op<15> = 1 | o2<13> = 0 | Pg<12:10> | Zn<9:5>
2819*f5c631daSSadaf Ebrahimi   //  | ne<4> = 0 | Pd<3:0>
2820*f5c631daSSadaf Ebrahimi 
2821*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2822*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, zn));
2823*f5c631daSSadaf Ebrahimi 
2824*f5c631daSSadaf Ebrahimi   CompareVectors(pd, pg, zn, imm5, CMPEQ_p_p_zi);
2825*f5c631daSSadaf Ebrahimi }
2826*f5c631daSSadaf Ebrahimi 
cmpge(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,int imm5)2827*f5c631daSSadaf Ebrahimi void Assembler::cmpge(const PRegisterWithLaneSize& pd,
2828*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
2829*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
2830*f5c631daSSadaf Ebrahimi                       int imm5) {
2831*f5c631daSSadaf Ebrahimi   // CMPGE <Pd>.<T>, <Pg>/Z, <Zn>.<T>, #<imm>
2832*f5c631daSSadaf Ebrahimi   //  0010 0101 ..0. .... 000. .... ...0 ....
2833*f5c631daSSadaf Ebrahimi   //  size<23:22> | imm5<20:16> | op<15> = 0 | o2<13> = 0 | Pg<12:10> | Zn<9:5>
2834*f5c631daSSadaf Ebrahimi   //  | ne<4> = 0 | Pd<3:0>
2835*f5c631daSSadaf Ebrahimi 
2836*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2837*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, zn));
2838*f5c631daSSadaf Ebrahimi 
2839*f5c631daSSadaf Ebrahimi   CompareVectors(pd, pg, zn, imm5, CMPGE_p_p_zi);
2840*f5c631daSSadaf Ebrahimi }
2841*f5c631daSSadaf Ebrahimi 
cmpgt(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,int imm5)2842*f5c631daSSadaf Ebrahimi void Assembler::cmpgt(const PRegisterWithLaneSize& pd,
2843*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
2844*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
2845*f5c631daSSadaf Ebrahimi                       int imm5) {
2846*f5c631daSSadaf Ebrahimi   // CMPGT <Pd>.<T>, <Pg>/Z, <Zn>.<T>, #<imm>
2847*f5c631daSSadaf Ebrahimi   //  0010 0101 ..0. .... 000. .... ...1 ....
2848*f5c631daSSadaf Ebrahimi   //  size<23:22> | imm5<20:16> | op<15> = 0 | o2<13> = 0 | Pg<12:10> | Zn<9:5>
2849*f5c631daSSadaf Ebrahimi   //  | ne<4> = 1 | Pd<3:0>
2850*f5c631daSSadaf Ebrahimi 
2851*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2852*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, zn));
2853*f5c631daSSadaf Ebrahimi 
2854*f5c631daSSadaf Ebrahimi   CompareVectors(pd, pg, zn, imm5, CMPGT_p_p_zi);
2855*f5c631daSSadaf Ebrahimi }
2856*f5c631daSSadaf Ebrahimi 
cmple(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,int imm5)2857*f5c631daSSadaf Ebrahimi void Assembler::cmple(const PRegisterWithLaneSize& pd,
2858*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
2859*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
2860*f5c631daSSadaf Ebrahimi                       int imm5) {
2861*f5c631daSSadaf Ebrahimi   // CMPLE <Pd>.<T>, <Pg>/Z, <Zn>.<T>, #<imm>
2862*f5c631daSSadaf Ebrahimi   //  0010 0101 ..0. .... 001. .... ...1 ....
2863*f5c631daSSadaf Ebrahimi   //  size<23:22> | imm5<20:16> | op<15> = 0 | o2<13> = 1 | Pg<12:10> | Zn<9:5>
2864*f5c631daSSadaf Ebrahimi   //  | ne<4> = 1 | Pd<3:0>
2865*f5c631daSSadaf Ebrahimi 
2866*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2867*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, zn));
2868*f5c631daSSadaf Ebrahimi 
2869*f5c631daSSadaf Ebrahimi   CompareVectors(pd, pg, zn, imm5, CMPLE_p_p_zi);
2870*f5c631daSSadaf Ebrahimi }
2871*f5c631daSSadaf Ebrahimi 
cmplt(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,int imm5)2872*f5c631daSSadaf Ebrahimi void Assembler::cmplt(const PRegisterWithLaneSize& pd,
2873*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
2874*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
2875*f5c631daSSadaf Ebrahimi                       int imm5) {
2876*f5c631daSSadaf Ebrahimi   // CMPLT <Pd>.<T>, <Pg>/Z, <Zn>.<T>, #<imm>
2877*f5c631daSSadaf Ebrahimi   //  0010 0101 ..0. .... 001. .... ...0 ....
2878*f5c631daSSadaf Ebrahimi   //  size<23:22> | imm5<20:16> | op<15> = 0 | o2<13> = 1 | Pg<12:10> | Zn<9:5>
2879*f5c631daSSadaf Ebrahimi   //  | ne<4> = 0 | Pd<3:0>
2880*f5c631daSSadaf Ebrahimi 
2881*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2882*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, zn));
2883*f5c631daSSadaf Ebrahimi 
2884*f5c631daSSadaf Ebrahimi   CompareVectors(pd, pg, zn, imm5, CMPLT_p_p_zi);
2885*f5c631daSSadaf Ebrahimi }
2886*f5c631daSSadaf Ebrahimi 
cmpne(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,int imm5)2887*f5c631daSSadaf Ebrahimi void Assembler::cmpne(const PRegisterWithLaneSize& pd,
2888*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
2889*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
2890*f5c631daSSadaf Ebrahimi                       int imm5) {
2891*f5c631daSSadaf Ebrahimi   // CMPNE <Pd>.<T>, <Pg>/Z, <Zn>.<T>, #<imm>
2892*f5c631daSSadaf Ebrahimi   //  0010 0101 ..0. .... 100. .... ...1 ....
2893*f5c631daSSadaf Ebrahimi   //  size<23:22> | imm5<20:16> | op<15> = 1 | o2<13> = 0 | Pg<12:10> | Zn<9:5>
2894*f5c631daSSadaf Ebrahimi   //  | ne<4> = 1 | Pd<3:0>
2895*f5c631daSSadaf Ebrahimi 
2896*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2897*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, zn));
2898*f5c631daSSadaf Ebrahimi 
2899*f5c631daSSadaf Ebrahimi   CompareVectors(pd, pg, zn, imm5, CMPNE_p_p_zi);
2900*f5c631daSSadaf Ebrahimi }
2901*f5c631daSSadaf Ebrahimi 
2902*f5c631daSSadaf Ebrahimi // SVEIntCompareUnsignedImm.
2903*f5c631daSSadaf Ebrahimi 
cmphi(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,unsigned imm7)2904*f5c631daSSadaf Ebrahimi void Assembler::cmphi(const PRegisterWithLaneSize& pd,
2905*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
2906*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
2907*f5c631daSSadaf Ebrahimi                       unsigned imm7) {
2908*f5c631daSSadaf Ebrahimi   // CMPHI <Pd>.<T>, <Pg>/Z, <Zn>.<T>, #<imm>
2909*f5c631daSSadaf Ebrahimi   //  0010 0100 ..1. .... ..0. .... ...1 ....
2910*f5c631daSSadaf Ebrahimi   //  size<23:22> | imm7<20:14> | lt<13> = 0 | Pg<12:10> | Zn<9:5> | ne<4> = 1 |
2911*f5c631daSSadaf Ebrahimi   //  Pd<3:0>
2912*f5c631daSSadaf Ebrahimi 
2913*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2914*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, zn));
2915*f5c631daSSadaf Ebrahimi 
2916*f5c631daSSadaf Ebrahimi   CompareVectors(pd, pg, zn, imm7, CMPHI_p_p_zi);
2917*f5c631daSSadaf Ebrahimi }
2918*f5c631daSSadaf Ebrahimi 
cmphs(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,unsigned imm7)2919*f5c631daSSadaf Ebrahimi void Assembler::cmphs(const PRegisterWithLaneSize& pd,
2920*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
2921*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
2922*f5c631daSSadaf Ebrahimi                       unsigned imm7) {
2923*f5c631daSSadaf Ebrahimi   // CMPHS <Pd>.<T>, <Pg>/Z, <Zn>.<T>, #<imm>
2924*f5c631daSSadaf Ebrahimi   //  0010 0100 ..1. .... ..0. .... ...0 ....
2925*f5c631daSSadaf Ebrahimi   //  size<23:22> | imm7<20:14> | lt<13> = 0 | Pg<12:10> | Zn<9:5> | ne<4> = 0 |
2926*f5c631daSSadaf Ebrahimi   //  Pd<3:0>
2927*f5c631daSSadaf Ebrahimi 
2928*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2929*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, zn));
2930*f5c631daSSadaf Ebrahimi 
2931*f5c631daSSadaf Ebrahimi   CompareVectors(pd, pg, zn, imm7, CMPHS_p_p_zi);
2932*f5c631daSSadaf Ebrahimi }
2933*f5c631daSSadaf Ebrahimi 
cmplo(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,unsigned imm7)2934*f5c631daSSadaf Ebrahimi void Assembler::cmplo(const PRegisterWithLaneSize& pd,
2935*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
2936*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
2937*f5c631daSSadaf Ebrahimi                       unsigned imm7) {
2938*f5c631daSSadaf Ebrahimi   // CMPLO <Pd>.<T>, <Pg>/Z, <Zn>.<T>, #<imm>
2939*f5c631daSSadaf Ebrahimi   //  0010 0100 ..1. .... ..1. .... ...0 ....
2940*f5c631daSSadaf Ebrahimi   //  size<23:22> | imm7<20:14> | lt<13> = 1 | Pg<12:10> | Zn<9:5> | ne<4> = 0 |
2941*f5c631daSSadaf Ebrahimi   //  Pd<3:0>
2942*f5c631daSSadaf Ebrahimi 
2943*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2944*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, zn));
2945*f5c631daSSadaf Ebrahimi 
2946*f5c631daSSadaf Ebrahimi   CompareVectors(pd, pg, zn, imm7, CMPLO_p_p_zi);
2947*f5c631daSSadaf Ebrahimi }
2948*f5c631daSSadaf Ebrahimi 
cmpls(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,unsigned imm7)2949*f5c631daSSadaf Ebrahimi void Assembler::cmpls(const PRegisterWithLaneSize& pd,
2950*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
2951*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
2952*f5c631daSSadaf Ebrahimi                       unsigned imm7) {
2953*f5c631daSSadaf Ebrahimi   // CMPLS <Pd>.<T>, <Pg>/Z, <Zn>.<T>, #<imm>
2954*f5c631daSSadaf Ebrahimi   //  0010 0100 ..1. .... ..1. .... ...1 ....
2955*f5c631daSSadaf Ebrahimi   //  size<23:22> | imm7<20:14> | lt<13> = 1 | Pg<12:10> | Zn<9:5> | ne<4> = 1 |
2956*f5c631daSSadaf Ebrahimi   //  Pd<3:0>
2957*f5c631daSSadaf Ebrahimi 
2958*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2959*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, zn));
2960*f5c631daSSadaf Ebrahimi 
2961*f5c631daSSadaf Ebrahimi   CompareVectors(pd, pg, zn, imm7, CMPLS_p_p_zi);
2962*f5c631daSSadaf Ebrahimi }
2963*f5c631daSSadaf Ebrahimi 
2964*f5c631daSSadaf Ebrahimi // SVEIntCompareVectors.
2965*f5c631daSSadaf Ebrahimi 
2966*f5c631daSSadaf Ebrahimi // This prototype maps to 2 instruction encodings:
2967*f5c631daSSadaf Ebrahimi //  CMPEQ_p_p_zw
2968*f5c631daSSadaf Ebrahimi //  CMPEQ_p_p_zz
cmpeq(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)2969*f5c631daSSadaf Ebrahimi void Assembler::cmpeq(const PRegisterWithLaneSize& pd,
2970*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
2971*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
2972*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
2973*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2974*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, zn));
2975*f5c631daSSadaf Ebrahimi   SVEIntCompareVectorsOp op = CMPEQ_p_p_zz;
2976*f5c631daSSadaf Ebrahimi   if (!AreSameLaneSize(zn, zm)) {
2977*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zm.IsLaneSizeD());
2978*f5c631daSSadaf Ebrahimi     op = CMPEQ_p_p_zw;
2979*f5c631daSSadaf Ebrahimi   }
2980*f5c631daSSadaf Ebrahimi   CompareVectors(pd, pg, zn, zm, op);
2981*f5c631daSSadaf Ebrahimi }
2982*f5c631daSSadaf Ebrahimi 
2983*f5c631daSSadaf Ebrahimi // This prototype maps to 2 instruction encodings:
2984*f5c631daSSadaf Ebrahimi //  CMPGE_p_p_zw
2985*f5c631daSSadaf Ebrahimi //  CMPGE_p_p_zz
cmpge(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)2986*f5c631daSSadaf Ebrahimi void Assembler::cmpge(const PRegisterWithLaneSize& pd,
2987*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
2988*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
2989*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
2990*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
2991*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, zn));
2992*f5c631daSSadaf Ebrahimi   SVEIntCompareVectorsOp op = CMPGE_p_p_zz;
2993*f5c631daSSadaf Ebrahimi   if (!AreSameLaneSize(zn, zm)) {
2994*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zm.IsLaneSizeD());
2995*f5c631daSSadaf Ebrahimi     op = CMPGE_p_p_zw;
2996*f5c631daSSadaf Ebrahimi   }
2997*f5c631daSSadaf Ebrahimi   CompareVectors(pd, pg, zn, zm, op);
2998*f5c631daSSadaf Ebrahimi }
2999*f5c631daSSadaf Ebrahimi 
3000*f5c631daSSadaf Ebrahimi // This prototype maps to 2 instruction encodings:
3001*f5c631daSSadaf Ebrahimi //  CMPGT_p_p_zw
3002*f5c631daSSadaf Ebrahimi //  CMPGT_p_p_zz
cmpgt(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)3003*f5c631daSSadaf Ebrahimi void Assembler::cmpgt(const PRegisterWithLaneSize& pd,
3004*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
3005*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
3006*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
3007*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3008*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, zn));
3009*f5c631daSSadaf Ebrahimi   SVEIntCompareVectorsOp op = CMPGT_p_p_zz;
3010*f5c631daSSadaf Ebrahimi   if (!AreSameLaneSize(zn, zm)) {
3011*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zm.IsLaneSizeD());
3012*f5c631daSSadaf Ebrahimi     op = CMPGT_p_p_zw;
3013*f5c631daSSadaf Ebrahimi   }
3014*f5c631daSSadaf Ebrahimi   CompareVectors(pd, pg, zn, zm, op);
3015*f5c631daSSadaf Ebrahimi }
3016*f5c631daSSadaf Ebrahimi 
3017*f5c631daSSadaf Ebrahimi // This prototype maps to 2 instruction encodings:
3018*f5c631daSSadaf Ebrahimi //  CMPHI_p_p_zw
3019*f5c631daSSadaf Ebrahimi //  CMPHI_p_p_zz
cmphi(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)3020*f5c631daSSadaf Ebrahimi void Assembler::cmphi(const PRegisterWithLaneSize& pd,
3021*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
3022*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
3023*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
3024*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3025*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, zn));
3026*f5c631daSSadaf Ebrahimi   SVEIntCompareVectorsOp op = CMPHI_p_p_zz;
3027*f5c631daSSadaf Ebrahimi   if (!AreSameLaneSize(zn, zm)) {
3028*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zm.IsLaneSizeD());
3029*f5c631daSSadaf Ebrahimi     op = CMPHI_p_p_zw;
3030*f5c631daSSadaf Ebrahimi   }
3031*f5c631daSSadaf Ebrahimi   CompareVectors(pd, pg, zn, zm, op);
3032*f5c631daSSadaf Ebrahimi }
3033*f5c631daSSadaf Ebrahimi 
3034*f5c631daSSadaf Ebrahimi // This prototype maps to 2 instruction encodings:
3035*f5c631daSSadaf Ebrahimi //  CMPHS_p_p_zw
3036*f5c631daSSadaf Ebrahimi //  CMPHS_p_p_zz
cmphs(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)3037*f5c631daSSadaf Ebrahimi void Assembler::cmphs(const PRegisterWithLaneSize& pd,
3038*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
3039*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
3040*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
3041*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3042*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, zn));
3043*f5c631daSSadaf Ebrahimi   SVEIntCompareVectorsOp op = CMPHS_p_p_zz;
3044*f5c631daSSadaf Ebrahimi   if (!AreSameLaneSize(zn, zm)) {
3045*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zm.IsLaneSizeD());
3046*f5c631daSSadaf Ebrahimi     op = CMPHS_p_p_zw;
3047*f5c631daSSadaf Ebrahimi   }
3048*f5c631daSSadaf Ebrahimi   CompareVectors(pd, pg, zn, zm, op);
3049*f5c631daSSadaf Ebrahimi }
3050*f5c631daSSadaf Ebrahimi 
cmple(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)3051*f5c631daSSadaf Ebrahimi void Assembler::cmple(const PRegisterWithLaneSize& pd,
3052*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
3053*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
3054*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
3055*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3056*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, zn));
3057*f5c631daSSadaf Ebrahimi   if (AreSameLaneSize(zn, zm)) {
3058*f5c631daSSadaf Ebrahimi     cmpge(pd, pg, zm, zn);
3059*f5c631daSSadaf Ebrahimi     return;
3060*f5c631daSSadaf Ebrahimi   }
3061*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zm.IsLaneSizeD());
3062*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zn.IsLaneSizeD());
3063*f5c631daSSadaf Ebrahimi 
3064*f5c631daSSadaf Ebrahimi   CompareVectors(pd, pg, zn, zm, CMPLE_p_p_zw);
3065*f5c631daSSadaf Ebrahimi }
3066*f5c631daSSadaf Ebrahimi 
cmplo(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)3067*f5c631daSSadaf Ebrahimi void Assembler::cmplo(const PRegisterWithLaneSize& pd,
3068*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
3069*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
3070*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
3071*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3072*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, zn));
3073*f5c631daSSadaf Ebrahimi   if (AreSameLaneSize(zn, zm)) {
3074*f5c631daSSadaf Ebrahimi     cmphi(pd, pg, zm, zn);
3075*f5c631daSSadaf Ebrahimi     return;
3076*f5c631daSSadaf Ebrahimi   }
3077*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zm.IsLaneSizeD());
3078*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zn.IsLaneSizeD());
3079*f5c631daSSadaf Ebrahimi 
3080*f5c631daSSadaf Ebrahimi   CompareVectors(pd, pg, zn, zm, CMPLO_p_p_zw);
3081*f5c631daSSadaf Ebrahimi }
3082*f5c631daSSadaf Ebrahimi 
cmpls(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)3083*f5c631daSSadaf Ebrahimi void Assembler::cmpls(const PRegisterWithLaneSize& pd,
3084*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
3085*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
3086*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
3087*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3088*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, zn));
3089*f5c631daSSadaf Ebrahimi   if (AreSameLaneSize(zn, zm)) {
3090*f5c631daSSadaf Ebrahimi     cmphs(pd, pg, zm, zn);
3091*f5c631daSSadaf Ebrahimi     return;
3092*f5c631daSSadaf Ebrahimi   }
3093*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zm.IsLaneSizeD());
3094*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zn.IsLaneSizeD());
3095*f5c631daSSadaf Ebrahimi 
3096*f5c631daSSadaf Ebrahimi   CompareVectors(pd, pg, zn, zm, CMPLS_p_p_zw);
3097*f5c631daSSadaf Ebrahimi }
3098*f5c631daSSadaf Ebrahimi 
cmplt(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)3099*f5c631daSSadaf Ebrahimi void Assembler::cmplt(const PRegisterWithLaneSize& pd,
3100*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
3101*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
3102*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
3103*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3104*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, zn));
3105*f5c631daSSadaf Ebrahimi   if (AreSameLaneSize(zn, zm)) {
3106*f5c631daSSadaf Ebrahimi     cmpgt(pd, pg, zm, zn);
3107*f5c631daSSadaf Ebrahimi     return;
3108*f5c631daSSadaf Ebrahimi   }
3109*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zm.IsLaneSizeD());
3110*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zn.IsLaneSizeD());
3111*f5c631daSSadaf Ebrahimi 
3112*f5c631daSSadaf Ebrahimi   CompareVectors(pd, pg, zn, zm, CMPLT_p_p_zw);
3113*f5c631daSSadaf Ebrahimi }
3114*f5c631daSSadaf Ebrahimi 
3115*f5c631daSSadaf Ebrahimi // This prototype maps to 2 instruction encodings:
3116*f5c631daSSadaf Ebrahimi //  CMPNE_p_p_zw
3117*f5c631daSSadaf Ebrahimi //  CMPNE_p_p_zz
cmpne(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)3118*f5c631daSSadaf Ebrahimi void Assembler::cmpne(const PRegisterWithLaneSize& pd,
3119*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
3120*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
3121*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
3122*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3123*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, zn));
3124*f5c631daSSadaf Ebrahimi   SVEIntCompareVectorsOp op = CMPNE_p_p_zz;
3125*f5c631daSSadaf Ebrahimi   if (!AreSameLaneSize(zn, zm)) {
3126*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zm.IsLaneSizeD());
3127*f5c631daSSadaf Ebrahimi     op = CMPNE_p_p_zw;
3128*f5c631daSSadaf Ebrahimi   }
3129*f5c631daSSadaf Ebrahimi   CompareVectors(pd, pg, zn, zm, op);
3130*f5c631daSSadaf Ebrahimi }
3131*f5c631daSSadaf Ebrahimi 
3132*f5c631daSSadaf Ebrahimi // SVEIntMiscUnpredicated.
3133*f5c631daSSadaf Ebrahimi 
fexpa(const ZRegister & zd,const ZRegister & zn)3134*f5c631daSSadaf Ebrahimi void Assembler::fexpa(const ZRegister& zd, const ZRegister& zn) {
3135*f5c631daSSadaf Ebrahimi   // FEXPA <Zd>.<T>, <Zn>.<T>
3136*f5c631daSSadaf Ebrahimi   //  0000 0100 ..10 0000 1011 10.. .... ....
3137*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<20:16> = 00000 | Zn<9:5> | Zd<4:0>
3138*f5c631daSSadaf Ebrahimi 
3139*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3140*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3141*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
3142*f5c631daSSadaf Ebrahimi 
3143*f5c631daSSadaf Ebrahimi   Emit(FEXPA_z_z | SVESize(zd) | Rd(zd) | Rn(zn));
3144*f5c631daSSadaf Ebrahimi }
3145*f5c631daSSadaf Ebrahimi 
ftssel(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)3146*f5c631daSSadaf Ebrahimi void Assembler::ftssel(const ZRegister& zd,
3147*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
3148*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
3149*f5c631daSSadaf Ebrahimi   // FTSSEL <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
3150*f5c631daSSadaf Ebrahimi   //  0000 0100 ..1. .... 1011 00.. .... ....
3151*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<10> = 0 | Zn<9:5> | Zd<4:0>
3152*f5c631daSSadaf Ebrahimi 
3153*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3154*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
3155*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
3156*f5c631daSSadaf Ebrahimi 
3157*f5c631daSSadaf Ebrahimi   Emit(FTSSEL_z_zz | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
3158*f5c631daSSadaf Ebrahimi }
3159*f5c631daSSadaf Ebrahimi 
movprfx(const ZRegister & zd,const ZRegister & zn)3160*f5c631daSSadaf Ebrahimi void Assembler::movprfx(const ZRegister& zd, const ZRegister& zn) {
3161*f5c631daSSadaf Ebrahimi   // MOVPRFX <Zd>, <Zn>
3162*f5c631daSSadaf Ebrahimi   //  0000 0100 0010 0000 1011 11.. .... ....
3163*f5c631daSSadaf Ebrahimi   //  opc<23:22> = 00 | opc2<20:16> = 00000 | Zn<9:5> | Zd<4:0>
3164*f5c631daSSadaf Ebrahimi 
3165*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3166*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3167*f5c631daSSadaf Ebrahimi 
3168*f5c631daSSadaf Ebrahimi   Emit(MOVPRFX_z_z | Rd(zd) | Rn(zn));
3169*f5c631daSSadaf Ebrahimi }
3170*f5c631daSSadaf Ebrahimi 
3171*f5c631daSSadaf Ebrahimi // SVEIntMulAddPredicated.
3172*f5c631daSSadaf Ebrahimi 
mad(const ZRegister & zdn,const PRegisterM & pg,const ZRegister & zm,const ZRegister & za)3173*f5c631daSSadaf Ebrahimi void Assembler::mad(const ZRegister& zdn,
3174*f5c631daSSadaf Ebrahimi                     const PRegisterM& pg,
3175*f5c631daSSadaf Ebrahimi                     const ZRegister& zm,
3176*f5c631daSSadaf Ebrahimi                     const ZRegister& za) {
3177*f5c631daSSadaf Ebrahimi   // MAD <Zdn>.<T>, <Pg>/M, <Zm>.<T>, <Za>.<T>
3178*f5c631daSSadaf Ebrahimi   //  0000 0100 ..0. .... 110. .... .... ....
3179*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<13> = 0 | Pg<12:10> | Za<9:5> | Zdn<4:0>
3180*f5c631daSSadaf Ebrahimi 
3181*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3182*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zdn, zm, za));
3183*f5c631daSSadaf Ebrahimi 
3184*f5c631daSSadaf Ebrahimi   Emit(MAD_z_p_zzz | SVESize(zdn) | Rd(zdn) | PgLow8(pg) | Rm(zm) | Rn(za));
3185*f5c631daSSadaf Ebrahimi }
3186*f5c631daSSadaf Ebrahimi 
mla(const ZRegister & zda,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)3187*f5c631daSSadaf Ebrahimi void Assembler::mla(const ZRegister& zda,
3188*f5c631daSSadaf Ebrahimi                     const PRegisterM& pg,
3189*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
3190*f5c631daSSadaf Ebrahimi                     const ZRegister& zm) {
3191*f5c631daSSadaf Ebrahimi   // MLA <Zda>.<T>, <Pg>/M, <Zn>.<T>, <Zm>.<T>
3192*f5c631daSSadaf Ebrahimi   //  0000 0100 ..0. .... 010. .... .... ....
3193*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<13> = 0 | Pg<12:10> | Zn<9:5> | Zda<4:0>
3194*f5c631daSSadaf Ebrahimi 
3195*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3196*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn, zm));
3197*f5c631daSSadaf Ebrahimi 
3198*f5c631daSSadaf Ebrahimi   Emit(MLA_z_p_zzz | SVESize(zda) | Rd(zda) | PgLow8(pg) | Rn(zn) | Rm(zm));
3199*f5c631daSSadaf Ebrahimi }
3200*f5c631daSSadaf Ebrahimi 
mls(const ZRegister & zda,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)3201*f5c631daSSadaf Ebrahimi void Assembler::mls(const ZRegister& zda,
3202*f5c631daSSadaf Ebrahimi                     const PRegisterM& pg,
3203*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
3204*f5c631daSSadaf Ebrahimi                     const ZRegister& zm) {
3205*f5c631daSSadaf Ebrahimi   // MLS <Zda>.<T>, <Pg>/M, <Zn>.<T>, <Zm>.<T>
3206*f5c631daSSadaf Ebrahimi   //  0000 0100 ..0. .... 011. .... .... ....
3207*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<13> = 1 | Pg<12:10> | Zn<9:5> | Zda<4:0>
3208*f5c631daSSadaf Ebrahimi 
3209*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3210*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn, zm));
3211*f5c631daSSadaf Ebrahimi 
3212*f5c631daSSadaf Ebrahimi   Emit(MLS_z_p_zzz | SVESize(zda) | Rd(zda) | PgLow8(pg) | Rn(zn) | Rm(zm));
3213*f5c631daSSadaf Ebrahimi }
3214*f5c631daSSadaf Ebrahimi 
msb(const ZRegister & zdn,const PRegisterM & pg,const ZRegister & zm,const ZRegister & za)3215*f5c631daSSadaf Ebrahimi void Assembler::msb(const ZRegister& zdn,
3216*f5c631daSSadaf Ebrahimi                     const PRegisterM& pg,
3217*f5c631daSSadaf Ebrahimi                     const ZRegister& zm,
3218*f5c631daSSadaf Ebrahimi                     const ZRegister& za) {
3219*f5c631daSSadaf Ebrahimi   // MSB <Zdn>.<T>, <Pg>/M, <Zm>.<T>, <Za>.<T>
3220*f5c631daSSadaf Ebrahimi   //  0000 0100 ..0. .... 111. .... .... ....
3221*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<13> = 1 | Pg<12:10> | Za<9:5> | Zdn<4:0>
3222*f5c631daSSadaf Ebrahimi 
3223*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3224*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zdn, zm, za));
3225*f5c631daSSadaf Ebrahimi 
3226*f5c631daSSadaf Ebrahimi   Emit(MSB_z_p_zzz | SVESize(zdn) | Rd(zdn) | PgLow8(pg) | Rm(zm) | Rn(za));
3227*f5c631daSSadaf Ebrahimi }
3228*f5c631daSSadaf Ebrahimi 
3229*f5c631daSSadaf Ebrahimi // SVEIntMulAddUnpredicated.
3230*f5c631daSSadaf Ebrahimi 
sdot(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)3231*f5c631daSSadaf Ebrahimi void Assembler::sdot(const ZRegister& zda,
3232*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
3233*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
3234*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3235*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.IsLaneSizeS() || zda.IsLaneSizeD());
3236*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 4));
3237*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zm, zn));
3238*f5c631daSSadaf Ebrahimi 
3239*f5c631daSSadaf Ebrahimi   Emit(SDOT_z_zzz | SVESize(zda) | Rd(zda) | Rn(zn) | Rm(zm));
3240*f5c631daSSadaf Ebrahimi }
3241*f5c631daSSadaf Ebrahimi 
udot(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)3242*f5c631daSSadaf Ebrahimi void Assembler::udot(const ZRegister& zda,
3243*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
3244*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
3245*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3246*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.IsLaneSizeS() || zda.IsLaneSizeD());
3247*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 4));
3248*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zm, zn));
3249*f5c631daSSadaf Ebrahimi 
3250*f5c631daSSadaf Ebrahimi   Emit(UDOT_z_zzz | SVESize(zda) | Rd(zda) | Rn(zn) | Rm(zm));
3251*f5c631daSSadaf Ebrahimi }
3252*f5c631daSSadaf Ebrahimi 
3253*f5c631daSSadaf Ebrahimi // SVEIntReduction.
3254*f5c631daSSadaf Ebrahimi 
andv(const VRegister & vd,const PRegister & pg,const ZRegister & zn)3255*f5c631daSSadaf Ebrahimi void Assembler::andv(const VRegister& vd,
3256*f5c631daSSadaf Ebrahimi                      const PRegister& pg,
3257*f5c631daSSadaf Ebrahimi                      const ZRegister& zn) {
3258*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3259*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(vd.IsScalar());
3260*f5c631daSSadaf Ebrahimi 
3261*f5c631daSSadaf Ebrahimi   Emit(ANDV_r_p_z | SVESize(zn) | Rd(vd) | PgLow8(pg) | Rn(zn));
3262*f5c631daSSadaf Ebrahimi }
3263*f5c631daSSadaf Ebrahimi 
eorv(const VRegister & vd,const PRegister & pg,const ZRegister & zn)3264*f5c631daSSadaf Ebrahimi void Assembler::eorv(const VRegister& vd,
3265*f5c631daSSadaf Ebrahimi                      const PRegister& pg,
3266*f5c631daSSadaf Ebrahimi                      const ZRegister& zn) {
3267*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3268*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(vd.IsScalar());
3269*f5c631daSSadaf Ebrahimi 
3270*f5c631daSSadaf Ebrahimi   Emit(EORV_r_p_z | SVESize(zn) | Rd(vd) | PgLow8(pg) | Rn(zn));
3271*f5c631daSSadaf Ebrahimi }
3272*f5c631daSSadaf Ebrahimi 
movprfx(const ZRegister & zd,const PRegister & pg,const ZRegister & zn)3273*f5c631daSSadaf Ebrahimi void Assembler::movprfx(const ZRegister& zd,
3274*f5c631daSSadaf Ebrahimi                         const PRegister& pg,
3275*f5c631daSSadaf Ebrahimi                         const ZRegister& zn) {
3276*f5c631daSSadaf Ebrahimi   // MOVPRFX <Zd>.<T>, <Pg>/<ZM>, <Zn>.<T>
3277*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 000. 001. .... .... ....
3278*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:17> = 00 | M<16> | Pg<12:10> | Zn<9:5> | Zd<4:0>
3279*f5c631daSSadaf Ebrahimi 
3280*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3281*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3282*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pg.IsMerging() || pg.IsZeroing());
3283*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!pg.HasLaneSize());
3284*f5c631daSSadaf Ebrahimi 
3285*f5c631daSSadaf Ebrahimi   Instr m = pg.IsMerging() ? 0x00010000 : 0x00000000;
3286*f5c631daSSadaf Ebrahimi   Emit(MOVPRFX_z_p_z | SVESize(zd) | m | Rd(zd) | PgLow8(pg) | Rn(zn));
3287*f5c631daSSadaf Ebrahimi }
3288*f5c631daSSadaf Ebrahimi 
orv(const VRegister & vd,const PRegister & pg,const ZRegister & zn)3289*f5c631daSSadaf Ebrahimi void Assembler::orv(const VRegister& vd,
3290*f5c631daSSadaf Ebrahimi                     const PRegister& pg,
3291*f5c631daSSadaf Ebrahimi                     const ZRegister& zn) {
3292*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3293*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(vd.IsScalar());
3294*f5c631daSSadaf Ebrahimi 
3295*f5c631daSSadaf Ebrahimi   Emit(ORV_r_p_z | SVESize(zn) | Rd(vd) | PgLow8(pg) | Rn(zn));
3296*f5c631daSSadaf Ebrahimi }
3297*f5c631daSSadaf Ebrahimi 
saddv(const VRegister & dd,const PRegister & pg,const ZRegister & zn)3298*f5c631daSSadaf Ebrahimi void Assembler::saddv(const VRegister& dd,
3299*f5c631daSSadaf Ebrahimi                       const PRegister& pg,
3300*f5c631daSSadaf Ebrahimi                       const ZRegister& zn) {
3301*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3302*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() != kDRegSizeInBytes);
3303*f5c631daSSadaf Ebrahimi 
3304*f5c631daSSadaf Ebrahimi   Emit(SADDV_r_p_z | SVESize(zn) | Rd(dd) | PgLow8(pg) | Rn(zn));
3305*f5c631daSSadaf Ebrahimi }
3306*f5c631daSSadaf Ebrahimi 
smaxv(const VRegister & vd,const PRegister & pg,const ZRegister & zn)3307*f5c631daSSadaf Ebrahimi void Assembler::smaxv(const VRegister& vd,
3308*f5c631daSSadaf Ebrahimi                       const PRegister& pg,
3309*f5c631daSSadaf Ebrahimi                       const ZRegister& zn) {
3310*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3311*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(vd.IsScalar());
3312*f5c631daSSadaf Ebrahimi 
3313*f5c631daSSadaf Ebrahimi   Emit(SMAXV_r_p_z | SVESize(zn) | Rd(vd) | PgLow8(pg) | Rn(zn));
3314*f5c631daSSadaf Ebrahimi }
3315*f5c631daSSadaf Ebrahimi 
sminv(const VRegister & vd,const PRegister & pg,const ZRegister & zn)3316*f5c631daSSadaf Ebrahimi void Assembler::sminv(const VRegister& vd,
3317*f5c631daSSadaf Ebrahimi                       const PRegister& pg,
3318*f5c631daSSadaf Ebrahimi                       const ZRegister& zn) {
3319*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3320*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(vd.IsScalar());
3321*f5c631daSSadaf Ebrahimi 
3322*f5c631daSSadaf Ebrahimi   Emit(SMINV_r_p_z | SVESize(zn) | Rd(vd) | PgLow8(pg) | Rn(zn));
3323*f5c631daSSadaf Ebrahimi }
3324*f5c631daSSadaf Ebrahimi 
uaddv(const VRegister & dd,const PRegister & pg,const ZRegister & zn)3325*f5c631daSSadaf Ebrahimi void Assembler::uaddv(const VRegister& dd,
3326*f5c631daSSadaf Ebrahimi                       const PRegister& pg,
3327*f5c631daSSadaf Ebrahimi                       const ZRegister& zn) {
3328*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3329*f5c631daSSadaf Ebrahimi 
3330*f5c631daSSadaf Ebrahimi   Emit(UADDV_r_p_z | SVESize(zn) | Rd(dd) | PgLow8(pg) | Rn(zn));
3331*f5c631daSSadaf Ebrahimi }
3332*f5c631daSSadaf Ebrahimi 
umaxv(const VRegister & vd,const PRegister & pg,const ZRegister & zn)3333*f5c631daSSadaf Ebrahimi void Assembler::umaxv(const VRegister& vd,
3334*f5c631daSSadaf Ebrahimi                       const PRegister& pg,
3335*f5c631daSSadaf Ebrahimi                       const ZRegister& zn) {
3336*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3337*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(vd.IsScalar());
3338*f5c631daSSadaf Ebrahimi 
3339*f5c631daSSadaf Ebrahimi   Emit(UMAXV_r_p_z | SVESize(zn) | Rd(vd) | PgLow8(pg) | Rn(zn));
3340*f5c631daSSadaf Ebrahimi }
3341*f5c631daSSadaf Ebrahimi 
uminv(const VRegister & vd,const PRegister & pg,const ZRegister & zn)3342*f5c631daSSadaf Ebrahimi void Assembler::uminv(const VRegister& vd,
3343*f5c631daSSadaf Ebrahimi                       const PRegister& pg,
3344*f5c631daSSadaf Ebrahimi                       const ZRegister& zn) {
3345*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3346*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(vd.IsScalar());
3347*f5c631daSSadaf Ebrahimi 
3348*f5c631daSSadaf Ebrahimi   Emit(UMINV_r_p_z | SVESize(zn) | Rd(vd) | PgLow8(pg) | Rn(zn));
3349*f5c631daSSadaf Ebrahimi }
3350*f5c631daSSadaf Ebrahimi 
3351*f5c631daSSadaf Ebrahimi // SVEIntUnaryArithmeticPredicated.
3352*f5c631daSSadaf Ebrahimi 
abs(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)3353*f5c631daSSadaf Ebrahimi void Assembler::abs(const ZRegister& zd,
3354*f5c631daSSadaf Ebrahimi                     const PRegisterM& pg,
3355*f5c631daSSadaf Ebrahimi                     const ZRegister& zn) {
3356*f5c631daSSadaf Ebrahimi   // ABS <Zd>.<T>, <Pg>/M, <Zn>.<T>
3357*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 0110 101. .... .... ....
3358*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 110 | Pg<12:10> | Zn<9:5> | Zd<4:0>
3359*f5c631daSSadaf Ebrahimi 
3360*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3361*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3362*f5c631daSSadaf Ebrahimi 
3363*f5c631daSSadaf Ebrahimi   Emit(ABS_z_p_z | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
3364*f5c631daSSadaf Ebrahimi }
3365*f5c631daSSadaf Ebrahimi 
cls(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)3366*f5c631daSSadaf Ebrahimi void Assembler::cls(const ZRegister& zd,
3367*f5c631daSSadaf Ebrahimi                     const PRegisterM& pg,
3368*f5c631daSSadaf Ebrahimi                     const ZRegister& zn) {
3369*f5c631daSSadaf Ebrahimi   // CLS <Zd>.<T>, <Pg>/M, <Zn>.<T>
3370*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 1000 101. .... .... ....
3371*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 000 | Pg<12:10> | Zn<9:5> | Zd<4:0>
3372*f5c631daSSadaf Ebrahimi 
3373*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3374*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3375*f5c631daSSadaf Ebrahimi 
3376*f5c631daSSadaf Ebrahimi   Emit(CLS_z_p_z | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
3377*f5c631daSSadaf Ebrahimi }
3378*f5c631daSSadaf Ebrahimi 
clz(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)3379*f5c631daSSadaf Ebrahimi void Assembler::clz(const ZRegister& zd,
3380*f5c631daSSadaf Ebrahimi                     const PRegisterM& pg,
3381*f5c631daSSadaf Ebrahimi                     const ZRegister& zn) {
3382*f5c631daSSadaf Ebrahimi   // CLZ <Zd>.<T>, <Pg>/M, <Zn>.<T>
3383*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 1001 101. .... .... ....
3384*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 001 | Pg<12:10> | Zn<9:5> | Zd<4:0>
3385*f5c631daSSadaf Ebrahimi 
3386*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3387*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3388*f5c631daSSadaf Ebrahimi 
3389*f5c631daSSadaf Ebrahimi   Emit(CLZ_z_p_z | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
3390*f5c631daSSadaf Ebrahimi }
3391*f5c631daSSadaf Ebrahimi 
cnot(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)3392*f5c631daSSadaf Ebrahimi void Assembler::cnot(const ZRegister& zd,
3393*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
3394*f5c631daSSadaf Ebrahimi                      const ZRegister& zn) {
3395*f5c631daSSadaf Ebrahimi   // CNOT <Zd>.<T>, <Pg>/M, <Zn>.<T>
3396*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 1011 101. .... .... ....
3397*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 011 | Pg<12:10> | Zn<9:5> | Zd<4:0>
3398*f5c631daSSadaf Ebrahimi 
3399*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3400*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3401*f5c631daSSadaf Ebrahimi 
3402*f5c631daSSadaf Ebrahimi   Emit(CNOT_z_p_z | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
3403*f5c631daSSadaf Ebrahimi }
3404*f5c631daSSadaf Ebrahimi 
cnt(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)3405*f5c631daSSadaf Ebrahimi void Assembler::cnt(const ZRegister& zd,
3406*f5c631daSSadaf Ebrahimi                     const PRegisterM& pg,
3407*f5c631daSSadaf Ebrahimi                     const ZRegister& zn) {
3408*f5c631daSSadaf Ebrahimi   // CNT <Zd>.<T>, <Pg>/M, <Zn>.<T>
3409*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 1010 101. .... .... ....
3410*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 010 | Pg<12:10> | Zn<9:5> | Zd<4:0>
3411*f5c631daSSadaf Ebrahimi 
3412*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3413*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3414*f5c631daSSadaf Ebrahimi 
3415*f5c631daSSadaf Ebrahimi   Emit(CNT_z_p_z | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
3416*f5c631daSSadaf Ebrahimi }
3417*f5c631daSSadaf Ebrahimi 
fabs(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)3418*f5c631daSSadaf Ebrahimi void Assembler::fabs(const ZRegister& zd,
3419*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
3420*f5c631daSSadaf Ebrahimi                      const ZRegister& zn) {
3421*f5c631daSSadaf Ebrahimi   // FABS <Zd>.<T>, <Pg>/M, <Zn>.<T>
3422*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 1100 101. .... .... ....
3423*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 100 | Pg<12:10> | Zn<9:5> | Zd<4:0>
3424*f5c631daSSadaf Ebrahimi 
3425*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3426*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3427*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
3428*f5c631daSSadaf Ebrahimi 
3429*f5c631daSSadaf Ebrahimi   Emit(FABS_z_p_z | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
3430*f5c631daSSadaf Ebrahimi }
3431*f5c631daSSadaf Ebrahimi 
fneg(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)3432*f5c631daSSadaf Ebrahimi void Assembler::fneg(const ZRegister& zd,
3433*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
3434*f5c631daSSadaf Ebrahimi                      const ZRegister& zn) {
3435*f5c631daSSadaf Ebrahimi   // FNEG <Zd>.<T>, <Pg>/M, <Zn>.<T>
3436*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 1101 101. .... .... ....
3437*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 101 | Pg<12:10> | Zn<9:5> | Zd<4:0>
3438*f5c631daSSadaf Ebrahimi 
3439*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3440*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3441*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
3442*f5c631daSSadaf Ebrahimi 
3443*f5c631daSSadaf Ebrahimi   Emit(FNEG_z_p_z | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
3444*f5c631daSSadaf Ebrahimi }
3445*f5c631daSSadaf Ebrahimi 
neg(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)3446*f5c631daSSadaf Ebrahimi void Assembler::neg(const ZRegister& zd,
3447*f5c631daSSadaf Ebrahimi                     const PRegisterM& pg,
3448*f5c631daSSadaf Ebrahimi                     const ZRegister& zn) {
3449*f5c631daSSadaf Ebrahimi   // NEG <Zd>.<T>, <Pg>/M, <Zn>.<T>
3450*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 0111 101. .... .... ....
3451*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 111 | Pg<12:10> | Zn<9:5> | Zd<4:0>
3452*f5c631daSSadaf Ebrahimi 
3453*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3454*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3455*f5c631daSSadaf Ebrahimi 
3456*f5c631daSSadaf Ebrahimi   Emit(NEG_z_p_z | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
3457*f5c631daSSadaf Ebrahimi }
3458*f5c631daSSadaf Ebrahimi 
not_(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)3459*f5c631daSSadaf Ebrahimi void Assembler::not_(const ZRegister& zd,
3460*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
3461*f5c631daSSadaf Ebrahimi                      const ZRegister& zn) {
3462*f5c631daSSadaf Ebrahimi   // NOT <Zd>.<T>, <Pg>/M, <Zn>.<T>
3463*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 1110 101. .... .... ....
3464*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 110 | Pg<12:10> | Zn<9:5> | Zd<4:0>
3465*f5c631daSSadaf Ebrahimi 
3466*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3467*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3468*f5c631daSSadaf Ebrahimi 
3469*f5c631daSSadaf Ebrahimi   Emit(NOT_z_p_z | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
3470*f5c631daSSadaf Ebrahimi }
3471*f5c631daSSadaf Ebrahimi 
sxtb(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)3472*f5c631daSSadaf Ebrahimi void Assembler::sxtb(const ZRegister& zd,
3473*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
3474*f5c631daSSadaf Ebrahimi                      const ZRegister& zn) {
3475*f5c631daSSadaf Ebrahimi   // SXTB <Zd>.<T>, <Pg>/M, <Zn>.<T>
3476*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 0000 101. .... .... ....
3477*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 000 | Pg<12:10> | Zn<9:5> | Zd<4:0>
3478*f5c631daSSadaf Ebrahimi 
3479*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3480*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3481*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() > kBRegSizeInBytes);
3482*f5c631daSSadaf Ebrahimi 
3483*f5c631daSSadaf Ebrahimi   Emit(SXTB_z_p_z | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
3484*f5c631daSSadaf Ebrahimi }
3485*f5c631daSSadaf Ebrahimi 
sxth(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)3486*f5c631daSSadaf Ebrahimi void Assembler::sxth(const ZRegister& zd,
3487*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
3488*f5c631daSSadaf Ebrahimi                      const ZRegister& zn) {
3489*f5c631daSSadaf Ebrahimi   // SXTH <Zd>.<T>, <Pg>/M, <Zn>.<T>
3490*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 0010 101. .... .... ....
3491*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 010 | Pg<12:10> | Zn<9:5> | Zd<4:0>
3492*f5c631daSSadaf Ebrahimi 
3493*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3494*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3495*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() > kHRegSizeInBytes);
3496*f5c631daSSadaf Ebrahimi 
3497*f5c631daSSadaf Ebrahimi   Emit(SXTH_z_p_z | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
3498*f5c631daSSadaf Ebrahimi }
3499*f5c631daSSadaf Ebrahimi 
sxtw(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)3500*f5c631daSSadaf Ebrahimi void Assembler::sxtw(const ZRegister& zd,
3501*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
3502*f5c631daSSadaf Ebrahimi                      const ZRegister& zn) {
3503*f5c631daSSadaf Ebrahimi   // SXTW <Zd>.D, <Pg>/M, <Zn>.D
3504*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 0100 101. .... .... ....
3505*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 100 | Pg<12:10> | Zn<9:5> | Zd<4:0>
3506*f5c631daSSadaf Ebrahimi 
3507*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3508*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3509*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() > kSRegSizeInBytes);
3510*f5c631daSSadaf Ebrahimi 
3511*f5c631daSSadaf Ebrahimi   Emit(SXTW_z_p_z | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
3512*f5c631daSSadaf Ebrahimi }
3513*f5c631daSSadaf Ebrahimi 
uxtb(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)3514*f5c631daSSadaf Ebrahimi void Assembler::uxtb(const ZRegister& zd,
3515*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
3516*f5c631daSSadaf Ebrahimi                      const ZRegister& zn) {
3517*f5c631daSSadaf Ebrahimi   // UXTB <Zd>.<T>, <Pg>/M, <Zn>.<T>
3518*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 0001 101. .... .... ....
3519*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 001 | Pg<12:10> | Zn<9:5> | Zd<4:0>
3520*f5c631daSSadaf Ebrahimi 
3521*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3522*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3523*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() > kBRegSizeInBytes);
3524*f5c631daSSadaf Ebrahimi 
3525*f5c631daSSadaf Ebrahimi   Emit(UXTB_z_p_z | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
3526*f5c631daSSadaf Ebrahimi }
3527*f5c631daSSadaf Ebrahimi 
uxth(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)3528*f5c631daSSadaf Ebrahimi void Assembler::uxth(const ZRegister& zd,
3529*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
3530*f5c631daSSadaf Ebrahimi                      const ZRegister& zn) {
3531*f5c631daSSadaf Ebrahimi   // UXTH <Zd>.<T>, <Pg>/M, <Zn>.<T>
3532*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 0011 101. .... .... ....
3533*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 011 | Pg<12:10> | Zn<9:5> | Zd<4:0>
3534*f5c631daSSadaf Ebrahimi 
3535*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3536*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3537*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() > kHRegSizeInBytes);
3538*f5c631daSSadaf Ebrahimi 
3539*f5c631daSSadaf Ebrahimi   Emit(UXTH_z_p_z | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
3540*f5c631daSSadaf Ebrahimi }
3541*f5c631daSSadaf Ebrahimi 
uxtw(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)3542*f5c631daSSadaf Ebrahimi void Assembler::uxtw(const ZRegister& zd,
3543*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
3544*f5c631daSSadaf Ebrahimi                      const ZRegister& zn) {
3545*f5c631daSSadaf Ebrahimi   // UXTW <Zd>.D, <Pg>/M, <Zn>.D
3546*f5c631daSSadaf Ebrahimi   //  0000 0100 ..01 0101 101. .... .... ....
3547*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 101 | Pg<12:10> | Zn<9:5> | Zd<4:0>
3548*f5c631daSSadaf Ebrahimi 
3549*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3550*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3551*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() > kSRegSizeInBytes);
3552*f5c631daSSadaf Ebrahimi 
3553*f5c631daSSadaf Ebrahimi   Emit(UXTW_z_p_z | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
3554*f5c631daSSadaf Ebrahimi }
3555*f5c631daSSadaf Ebrahimi 
3556*f5c631daSSadaf Ebrahimi // SVEIntWideImmPredicated.
3557*f5c631daSSadaf Ebrahimi 
cpy(const ZRegister & zd,const PRegister & pg,int imm8,int shift)3558*f5c631daSSadaf Ebrahimi void Assembler::cpy(const ZRegister& zd,
3559*f5c631daSSadaf Ebrahimi                     const PRegister& pg,
3560*f5c631daSSadaf Ebrahimi                     int imm8,
3561*f5c631daSSadaf Ebrahimi                     int shift) {
3562*f5c631daSSadaf Ebrahimi   // CPY <Zd>.<T>, <Pg>/<ZM>, #<imm>{, <shift>}
3563*f5c631daSSadaf Ebrahimi   //  0000 0101 ..01 .... 0... .... .... ....
3564*f5c631daSSadaf Ebrahimi   //  size<23:22> | Pg<19:16> | M<14> | sh<13> | imm8<12:5> | Zd<4:0>
3565*f5c631daSSadaf Ebrahimi 
3566*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3567*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pg.IsMerging() || pg.IsZeroing());
3568*f5c631daSSadaf Ebrahimi 
3569*f5c631daSSadaf Ebrahimi   ResolveSVEImm8Shift(&imm8, &shift);
3570*f5c631daSSadaf Ebrahimi 
3571*f5c631daSSadaf Ebrahimi   Instr sh = (shift > 0) ? (1 << 13) : 0;
3572*f5c631daSSadaf Ebrahimi   Instr m = pg.IsMerging() ? (1 << 14) : 0;
3573*f5c631daSSadaf Ebrahimi   Emit(CPY_z_p_i | m | sh | SVESize(zd) | Rd(zd) | Pg<19, 16>(pg) |
3574*f5c631daSSadaf Ebrahimi        ImmField<12, 5>(imm8));
3575*f5c631daSSadaf Ebrahimi }
3576*f5c631daSSadaf Ebrahimi 
fcpy(const ZRegister & zd,const PRegisterM & pg,double imm)3577*f5c631daSSadaf Ebrahimi void Assembler::fcpy(const ZRegister& zd, const PRegisterM& pg, double imm) {
3578*f5c631daSSadaf Ebrahimi   // FCPY <Zd>.<T>, <Pg>/M, #<const>
3579*f5c631daSSadaf Ebrahimi   //  0000 0101 ..01 .... 110. .... .... ....
3580*f5c631daSSadaf Ebrahimi   //  size<23:22> | Pg<19:16> | imm8<12:5> | Zd<4:0>
3581*f5c631daSSadaf Ebrahimi 
3582*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3583*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
3584*f5c631daSSadaf Ebrahimi 
3585*f5c631daSSadaf Ebrahimi   Instr imm_field = ImmUnsignedField<12, 5>(FP64ToImm8(imm));
3586*f5c631daSSadaf Ebrahimi   Emit(FCPY_z_p_i | SVESize(zd) | Rd(zd) | Pg<19, 16>(pg) | imm_field);
3587*f5c631daSSadaf Ebrahimi }
3588*f5c631daSSadaf Ebrahimi 
3589*f5c631daSSadaf Ebrahimi // SVEIntAddSubtractImmUnpredicated.
3590*f5c631daSSadaf Ebrahimi 
SVEIntAddSubtractImmUnpredicatedHelper(SVEIntAddSubtractImm_UnpredicatedOp op,const ZRegister & zd,int imm8,int shift)3591*f5c631daSSadaf Ebrahimi void Assembler::SVEIntAddSubtractImmUnpredicatedHelper(
3592*f5c631daSSadaf Ebrahimi     SVEIntAddSubtractImm_UnpredicatedOp op,
3593*f5c631daSSadaf Ebrahimi     const ZRegister& zd,
3594*f5c631daSSadaf Ebrahimi     int imm8,
3595*f5c631daSSadaf Ebrahimi     int shift) {
3596*f5c631daSSadaf Ebrahimi   if (shift < 0) {
3597*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(shift == -1);
3598*f5c631daSSadaf Ebrahimi     // Derive the shift amount from the immediate.
3599*f5c631daSSadaf Ebrahimi     if (IsUint8(imm8)) {
3600*f5c631daSSadaf Ebrahimi       shift = 0;
3601*f5c631daSSadaf Ebrahimi     } else if (IsUint16(imm8) && ((imm8 % 256) == 0)) {
3602*f5c631daSSadaf Ebrahimi       imm8 /= 256;
3603*f5c631daSSadaf Ebrahimi       shift = 8;
3604*f5c631daSSadaf Ebrahimi     }
3605*f5c631daSSadaf Ebrahimi   }
3606*f5c631daSSadaf Ebrahimi 
3607*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(IsUint8(imm8));
3608*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((shift == 0) || (shift == 8));
3609*f5c631daSSadaf Ebrahimi 
3610*f5c631daSSadaf Ebrahimi   Instr shift_bit = (shift > 0) ? (1 << 13) : 0;
3611*f5c631daSSadaf Ebrahimi   Emit(op | SVESize(zd) | Rd(zd) | shift_bit | ImmUnsignedField<12, 5>(imm8));
3612*f5c631daSSadaf Ebrahimi }
3613*f5c631daSSadaf Ebrahimi 
add(const ZRegister & zd,const ZRegister & zn,int imm8,int shift)3614*f5c631daSSadaf Ebrahimi void Assembler::add(const ZRegister& zd,
3615*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
3616*f5c631daSSadaf Ebrahimi                     int imm8,
3617*f5c631daSSadaf Ebrahimi                     int shift) {
3618*f5c631daSSadaf Ebrahimi   // ADD <Zdn>.<T>, <Zdn>.<T>, #<imm>{, <shift>}
3619*f5c631daSSadaf Ebrahimi   //  0010 0101 ..10 0000 11.. .... .... ....
3620*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 000 | sh<13> | imm8<12:5> | Zdn<4:0>
3621*f5c631daSSadaf Ebrahimi 
3622*f5c631daSSadaf Ebrahimi   USE(zn);
3623*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3624*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
3625*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3626*f5c631daSSadaf Ebrahimi 
3627*f5c631daSSadaf Ebrahimi   SVEIntAddSubtractImmUnpredicatedHelper(ADD_z_zi, zd, imm8, shift);
3628*f5c631daSSadaf Ebrahimi }
3629*f5c631daSSadaf Ebrahimi 
dup(const ZRegister & zd,int imm8,int shift)3630*f5c631daSSadaf Ebrahimi void Assembler::dup(const ZRegister& zd, int imm8, int shift) {
3631*f5c631daSSadaf Ebrahimi   // DUP <Zd>.<T>, #<imm>{, <shift>}
3632*f5c631daSSadaf Ebrahimi   //  0010 0101 ..11 1000 11.. .... .... ....
3633*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:17> = 00 | sh<13> | imm8<12:5> | Zd<4:0>
3634*f5c631daSSadaf Ebrahimi 
3635*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3636*f5c631daSSadaf Ebrahimi 
3637*f5c631daSSadaf Ebrahimi   ResolveSVEImm8Shift(&imm8, &shift);
3638*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((shift < 8) || !zd.IsLaneSizeB());
3639*f5c631daSSadaf Ebrahimi 
3640*f5c631daSSadaf Ebrahimi   Instr shift_bit = (shift > 0) ? (1 << 13) : 0;
3641*f5c631daSSadaf Ebrahimi   Emit(DUP_z_i | SVESize(zd) | Rd(zd) | shift_bit | ImmField<12, 5>(imm8));
3642*f5c631daSSadaf Ebrahimi }
3643*f5c631daSSadaf Ebrahimi 
fdup(const ZRegister & zd,double imm)3644*f5c631daSSadaf Ebrahimi void Assembler::fdup(const ZRegister& zd, double imm) {
3645*f5c631daSSadaf Ebrahimi   // FDUP <Zd>.<T>, #<const>
3646*f5c631daSSadaf Ebrahimi   //  0010 0101 ..11 1001 110. .... .... ....
3647*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:17> = 00 | o2<13> = 0 | imm8<12:5> | Zd<4:0>
3648*f5c631daSSadaf Ebrahimi 
3649*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3650*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
3651*f5c631daSSadaf Ebrahimi 
3652*f5c631daSSadaf Ebrahimi   Instr encoded_imm = FP64ToImm8(imm) << 5;
3653*f5c631daSSadaf Ebrahimi   Emit(FDUP_z_i | SVESize(zd) | encoded_imm | Rd(zd));
3654*f5c631daSSadaf Ebrahimi }
3655*f5c631daSSadaf Ebrahimi 
mul(const ZRegister & zd,const ZRegister & zn,int imm8)3656*f5c631daSSadaf Ebrahimi void Assembler::mul(const ZRegister& zd, const ZRegister& zn, int imm8) {
3657*f5c631daSSadaf Ebrahimi   // MUL <Zdn>.<T>, <Zdn>.<T>, #<imm>
3658*f5c631daSSadaf Ebrahimi   //  0010 0101 ..11 0000 110. .... .... ....
3659*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 000 | o2<13> = 0 | imm8<12:5> | Zdn<4:0>
3660*f5c631daSSadaf Ebrahimi 
3661*f5c631daSSadaf Ebrahimi   USE(zn);
3662*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3663*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
3664*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3665*f5c631daSSadaf Ebrahimi 
3666*f5c631daSSadaf Ebrahimi   Emit(MUL_z_zi | SVESize(zd) | Rd(zd) | ImmField<12, 5>(imm8));
3667*f5c631daSSadaf Ebrahimi }
3668*f5c631daSSadaf Ebrahimi 
smax(const ZRegister & zd,const ZRegister & zn,int imm8)3669*f5c631daSSadaf Ebrahimi void Assembler::smax(const ZRegister& zd, const ZRegister& zn, int imm8) {
3670*f5c631daSSadaf Ebrahimi   // SMAX <Zdn>.<T>, <Zdn>.<T>, #<imm>
3671*f5c631daSSadaf Ebrahimi   //  0010 0101 ..10 1000 110. .... .... ....
3672*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 000 | o2<13> = 0 | imm8<12:5> | Zdn<4:0>
3673*f5c631daSSadaf Ebrahimi 
3674*f5c631daSSadaf Ebrahimi   USE(zn);
3675*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3676*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
3677*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3678*f5c631daSSadaf Ebrahimi 
3679*f5c631daSSadaf Ebrahimi   Emit(SMAX_z_zi | SVESize(zd) | Rd(zd) | ImmField<12, 5>(imm8));
3680*f5c631daSSadaf Ebrahimi }
3681*f5c631daSSadaf Ebrahimi 
smin(const ZRegister & zd,const ZRegister & zn,int imm8)3682*f5c631daSSadaf Ebrahimi void Assembler::smin(const ZRegister& zd, const ZRegister& zn, int imm8) {
3683*f5c631daSSadaf Ebrahimi   // SMIN <Zdn>.<T>, <Zdn>.<T>, #<imm>
3684*f5c631daSSadaf Ebrahimi   //  0010 0101 ..10 1010 110. .... .... ....
3685*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 010 | o2<13> = 0 | imm8<12:5> | Zdn<4:0>
3686*f5c631daSSadaf Ebrahimi 
3687*f5c631daSSadaf Ebrahimi   USE(zn);
3688*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3689*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
3690*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3691*f5c631daSSadaf Ebrahimi 
3692*f5c631daSSadaf Ebrahimi   Emit(SMIN_z_zi | SVESize(zd) | Rd(zd) | ImmField<12, 5>(imm8));
3693*f5c631daSSadaf Ebrahimi }
3694*f5c631daSSadaf Ebrahimi 
sqadd(const ZRegister & zd,const ZRegister & zn,int imm8,int shift)3695*f5c631daSSadaf Ebrahimi void Assembler::sqadd(const ZRegister& zd,
3696*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
3697*f5c631daSSadaf Ebrahimi                       int imm8,
3698*f5c631daSSadaf Ebrahimi                       int shift) {
3699*f5c631daSSadaf Ebrahimi   // SQADD <Zdn>.<T>, <Zdn>.<T>, #<imm>{, <shift>}
3700*f5c631daSSadaf Ebrahimi   //  0010 0101 ..10 0100 11.. .... .... ....
3701*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 100 | sh<13> | imm8<12:5> | Zdn<4:0>
3702*f5c631daSSadaf Ebrahimi 
3703*f5c631daSSadaf Ebrahimi   USE(zn);
3704*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3705*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
3706*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3707*f5c631daSSadaf Ebrahimi 
3708*f5c631daSSadaf Ebrahimi   SVEIntAddSubtractImmUnpredicatedHelper(SQADD_z_zi, zd, imm8, shift);
3709*f5c631daSSadaf Ebrahimi }
3710*f5c631daSSadaf Ebrahimi 
sqsub(const ZRegister & zd,const ZRegister & zn,int imm8,int shift)3711*f5c631daSSadaf Ebrahimi void Assembler::sqsub(const ZRegister& zd,
3712*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
3713*f5c631daSSadaf Ebrahimi                       int imm8,
3714*f5c631daSSadaf Ebrahimi                       int shift) {
3715*f5c631daSSadaf Ebrahimi   // SQSUB <Zdn>.<T>, <Zdn>.<T>, #<imm>{, <shift>}
3716*f5c631daSSadaf Ebrahimi   //  0010 0101 ..10 0110 11.. .... .... ....
3717*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 110 | sh<13> | imm8<12:5> | Zdn<4:0>
3718*f5c631daSSadaf Ebrahimi 
3719*f5c631daSSadaf Ebrahimi   USE(zn);
3720*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3721*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
3722*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3723*f5c631daSSadaf Ebrahimi 
3724*f5c631daSSadaf Ebrahimi   SVEIntAddSubtractImmUnpredicatedHelper(SQSUB_z_zi, zd, imm8, shift);
3725*f5c631daSSadaf Ebrahimi }
3726*f5c631daSSadaf Ebrahimi 
sub(const ZRegister & zd,const ZRegister & zn,int imm8,int shift)3727*f5c631daSSadaf Ebrahimi void Assembler::sub(const ZRegister& zd,
3728*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
3729*f5c631daSSadaf Ebrahimi                     int imm8,
3730*f5c631daSSadaf Ebrahimi                     int shift) {
3731*f5c631daSSadaf Ebrahimi   // SUB <Zdn>.<T>, <Zdn>.<T>, #<imm>{, <shift>}
3732*f5c631daSSadaf Ebrahimi   //  0010 0101 ..10 0001 11.. .... .... ....
3733*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 001 | sh<13> | imm8<12:5> | Zdn<4:0>
3734*f5c631daSSadaf Ebrahimi 
3735*f5c631daSSadaf Ebrahimi   USE(zn);
3736*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3737*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
3738*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3739*f5c631daSSadaf Ebrahimi 
3740*f5c631daSSadaf Ebrahimi   SVEIntAddSubtractImmUnpredicatedHelper(SUB_z_zi, zd, imm8, shift);
3741*f5c631daSSadaf Ebrahimi }
3742*f5c631daSSadaf Ebrahimi 
subr(const ZRegister & zd,const ZRegister & zn,int imm8,int shift)3743*f5c631daSSadaf Ebrahimi void Assembler::subr(const ZRegister& zd,
3744*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
3745*f5c631daSSadaf Ebrahimi                      int imm8,
3746*f5c631daSSadaf Ebrahimi                      int shift) {
3747*f5c631daSSadaf Ebrahimi   // SUBR <Zdn>.<T>, <Zdn>.<T>, #<imm>{, <shift>}
3748*f5c631daSSadaf Ebrahimi   //  0010 0101 ..10 0011 11.. .... .... ....
3749*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 011 | sh<13> | imm8<12:5> | Zdn<4:0>
3750*f5c631daSSadaf Ebrahimi 
3751*f5c631daSSadaf Ebrahimi   USE(zn);
3752*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3753*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
3754*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3755*f5c631daSSadaf Ebrahimi 
3756*f5c631daSSadaf Ebrahimi   SVEIntAddSubtractImmUnpredicatedHelper(SUBR_z_zi, zd, imm8, shift);
3757*f5c631daSSadaf Ebrahimi }
3758*f5c631daSSadaf Ebrahimi 
umax(const ZRegister & zd,const ZRegister & zn,int imm8)3759*f5c631daSSadaf Ebrahimi void Assembler::umax(const ZRegister& zd, const ZRegister& zn, int imm8) {
3760*f5c631daSSadaf Ebrahimi   // UMAX <Zdn>.<T>, <Zdn>.<T>, #<imm>
3761*f5c631daSSadaf Ebrahimi   //  0010 0101 ..10 1001 110. .... .... ....
3762*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 001 | o2<13> = 0 | imm8<12:5> | Zdn<4:0>
3763*f5c631daSSadaf Ebrahimi 
3764*f5c631daSSadaf Ebrahimi   USE(zn);
3765*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3766*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
3767*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3768*f5c631daSSadaf Ebrahimi 
3769*f5c631daSSadaf Ebrahimi   Emit(UMAX_z_zi | SVESize(zd) | Rd(zd) | ImmUnsignedField<12, 5>(imm8));
3770*f5c631daSSadaf Ebrahimi }
3771*f5c631daSSadaf Ebrahimi 
umin(const ZRegister & zd,const ZRegister & zn,int imm8)3772*f5c631daSSadaf Ebrahimi void Assembler::umin(const ZRegister& zd, const ZRegister& zn, int imm8) {
3773*f5c631daSSadaf Ebrahimi   // UMIN <Zdn>.<T>, <Zdn>.<T>, #<imm>
3774*f5c631daSSadaf Ebrahimi   //  0010 0101 ..10 1011 110. .... .... ....
3775*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 011 | o2<13> = 0 | imm8<12:5> | Zdn<4:0>
3776*f5c631daSSadaf Ebrahimi 
3777*f5c631daSSadaf Ebrahimi   USE(zn);
3778*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3779*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
3780*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3781*f5c631daSSadaf Ebrahimi 
3782*f5c631daSSadaf Ebrahimi   Emit(UMIN_z_zi | SVESize(zd) | Rd(zd) | ImmUnsignedField<12, 5>(imm8));
3783*f5c631daSSadaf Ebrahimi }
3784*f5c631daSSadaf Ebrahimi 
uqadd(const ZRegister & zd,const ZRegister & zn,int imm8,int shift)3785*f5c631daSSadaf Ebrahimi void Assembler::uqadd(const ZRegister& zd,
3786*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
3787*f5c631daSSadaf Ebrahimi                       int imm8,
3788*f5c631daSSadaf Ebrahimi                       int shift) {
3789*f5c631daSSadaf Ebrahimi   // UQADD <Zdn>.<T>, <Zdn>.<T>, #<imm>{, <shift>}
3790*f5c631daSSadaf Ebrahimi   //  0010 0101 ..10 0101 11.. .... .... ....
3791*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 101 | sh<13> | imm8<12:5> | Zdn<4:0>
3792*f5c631daSSadaf Ebrahimi 
3793*f5c631daSSadaf Ebrahimi   USE(zn);
3794*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3795*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
3796*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3797*f5c631daSSadaf Ebrahimi 
3798*f5c631daSSadaf Ebrahimi   SVEIntAddSubtractImmUnpredicatedHelper(UQADD_z_zi, zd, imm8, shift);
3799*f5c631daSSadaf Ebrahimi }
3800*f5c631daSSadaf Ebrahimi 
uqsub(const ZRegister & zd,const ZRegister & zn,int imm8,int shift)3801*f5c631daSSadaf Ebrahimi void Assembler::uqsub(const ZRegister& zd,
3802*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
3803*f5c631daSSadaf Ebrahimi                       int imm8,
3804*f5c631daSSadaf Ebrahimi                       int shift) {
3805*f5c631daSSadaf Ebrahimi   // UQSUB <Zdn>.<T>, <Zdn>.<T>, #<imm>{, <shift>}
3806*f5c631daSSadaf Ebrahimi   //  0010 0101 ..10 0111 11.. .... .... ....
3807*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 111 | sh<13> | imm8<12:5> | Zdn<4:0>
3808*f5c631daSSadaf Ebrahimi 
3809*f5c631daSSadaf Ebrahimi   USE(zn);
3810*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
3811*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
3812*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
3813*f5c631daSSadaf Ebrahimi 
3814*f5c631daSSadaf Ebrahimi   SVEIntAddSubtractImmUnpredicatedHelper(UQSUB_z_zi, zd, imm8, shift);
3815*f5c631daSSadaf Ebrahimi }
3816*f5c631daSSadaf Ebrahimi 
3817*f5c631daSSadaf Ebrahimi // SVEMemLoad.
3818*f5c631daSSadaf Ebrahimi 
SVELdSt1Helper(unsigned msize_in_bytes_log2,const ZRegister & zt,const PRegister & pg,const SVEMemOperand & addr,bool is_signed,Instr op)3819*f5c631daSSadaf Ebrahimi void Assembler::SVELdSt1Helper(unsigned msize_in_bytes_log2,
3820*f5c631daSSadaf Ebrahimi                                const ZRegister& zt,
3821*f5c631daSSadaf Ebrahimi                                const PRegister& pg,
3822*f5c631daSSadaf Ebrahimi                                const SVEMemOperand& addr,
3823*f5c631daSSadaf Ebrahimi                                bool is_signed,
3824*f5c631daSSadaf Ebrahimi                                Instr op) {
3825*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsContiguous());
3826*f5c631daSSadaf Ebrahimi 
3827*f5c631daSSadaf Ebrahimi   Instr mem_op = SVEMemOperandHelper(msize_in_bytes_log2, 1, addr);
3828*f5c631daSSadaf Ebrahimi   Instr dtype =
3829*f5c631daSSadaf Ebrahimi       SVEDtype(msize_in_bytes_log2, zt.GetLaneSizeInBytesLog2(), is_signed);
3830*f5c631daSSadaf Ebrahimi   Emit(op | mem_op | dtype | Rt(zt) | PgLow8(pg));
3831*f5c631daSSadaf Ebrahimi }
3832*f5c631daSSadaf Ebrahimi 
SVELdSt234Helper(int num_regs,const ZRegister & zt1,const PRegister & pg,const SVEMemOperand & addr,Instr op)3833*f5c631daSSadaf Ebrahimi void Assembler::SVELdSt234Helper(int num_regs,
3834*f5c631daSSadaf Ebrahimi                                  const ZRegister& zt1,
3835*f5c631daSSadaf Ebrahimi                                  const PRegister& pg,
3836*f5c631daSSadaf Ebrahimi                                  const SVEMemOperand& addr,
3837*f5c631daSSadaf Ebrahimi                                  Instr op) {
3838*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((num_regs >= 2) && (num_regs <= 4));
3839*f5c631daSSadaf Ebrahimi 
3840*f5c631daSSadaf Ebrahimi   unsigned msize_in_bytes_log2 = zt1.GetLaneSizeInBytesLog2();
3841*f5c631daSSadaf Ebrahimi   Instr num = (num_regs - 1) << 21;
3842*f5c631daSSadaf Ebrahimi   Instr msz = msize_in_bytes_log2 << 23;
3843*f5c631daSSadaf Ebrahimi   Instr mem_op = SVEMemOperandHelper(msize_in_bytes_log2, num_regs, addr);
3844*f5c631daSSadaf Ebrahimi   Emit(op | mem_op | msz | num | Rt(zt1) | PgLow8(pg));
3845*f5c631daSSadaf Ebrahimi }
3846*f5c631daSSadaf Ebrahimi 
SVELd1Helper(unsigned msize_in_bytes_log2,const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr,bool is_signed)3847*f5c631daSSadaf Ebrahimi void Assembler::SVELd1Helper(unsigned msize_in_bytes_log2,
3848*f5c631daSSadaf Ebrahimi                              const ZRegister& zt,
3849*f5c631daSSadaf Ebrahimi                              const PRegisterZ& pg,
3850*f5c631daSSadaf Ebrahimi                              const SVEMemOperand& addr,
3851*f5c631daSSadaf Ebrahimi                              bool is_signed) {
3852*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zt.GetLaneSizeInBytesLog2() >= msize_in_bytes_log2);
3853*f5c631daSSadaf Ebrahimi   if (is_signed) {
3854*f5c631daSSadaf Ebrahimi     // Sign-extension is only possible when the vector elements are larger than
3855*f5c631daSSadaf Ebrahimi     // the elements in memory.
3856*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zt.GetLaneSizeInBytesLog2() != msize_in_bytes_log2);
3857*f5c631daSSadaf Ebrahimi   }
3858*f5c631daSSadaf Ebrahimi 
3859*f5c631daSSadaf Ebrahimi   if (addr.IsScatterGather()) {
3860*f5c631daSSadaf Ebrahimi     bool is_load = true;
3861*f5c631daSSadaf Ebrahimi     bool is_ff = false;
3862*f5c631daSSadaf Ebrahimi     SVEScatterGatherHelper(msize_in_bytes_log2,
3863*f5c631daSSadaf Ebrahimi                            zt,
3864*f5c631daSSadaf Ebrahimi                            pg,
3865*f5c631daSSadaf Ebrahimi                            addr,
3866*f5c631daSSadaf Ebrahimi                            is_load,
3867*f5c631daSSadaf Ebrahimi                            is_signed,
3868*f5c631daSSadaf Ebrahimi                            is_ff);
3869*f5c631daSSadaf Ebrahimi     return;
3870*f5c631daSSadaf Ebrahimi   }
3871*f5c631daSSadaf Ebrahimi 
3872*f5c631daSSadaf Ebrahimi   Instr op = 0xffffffff;
3873*f5c631daSSadaf Ebrahimi   if (addr.IsScalarPlusImmediate()) {
3874*f5c631daSSadaf Ebrahimi     op = SVEContiguousLoad_ScalarPlusImmFixed;
3875*f5c631daSSadaf Ebrahimi   } else if (addr.IsScalarPlusScalar()) {
3876*f5c631daSSadaf Ebrahimi     // Rm must not be xzr.
3877*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(!addr.GetScalarOffset().IsZero());
3878*f5c631daSSadaf Ebrahimi     op = SVEContiguousLoad_ScalarPlusScalarFixed;
3879*f5c631daSSadaf Ebrahimi   } else {
3880*f5c631daSSadaf Ebrahimi     VIXL_UNIMPLEMENTED();
3881*f5c631daSSadaf Ebrahimi   }
3882*f5c631daSSadaf Ebrahimi   SVELdSt1Helper(msize_in_bytes_log2, zt, pg, addr, is_signed, op);
3883*f5c631daSSadaf Ebrahimi }
3884*f5c631daSSadaf Ebrahimi 
SVELdff1Helper(unsigned msize_in_bytes_log2,const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr,bool is_signed)3885*f5c631daSSadaf Ebrahimi void Assembler::SVELdff1Helper(unsigned msize_in_bytes_log2,
3886*f5c631daSSadaf Ebrahimi                                const ZRegister& zt,
3887*f5c631daSSadaf Ebrahimi                                const PRegisterZ& pg,
3888*f5c631daSSadaf Ebrahimi                                const SVEMemOperand& addr,
3889*f5c631daSSadaf Ebrahimi                                bool is_signed) {
3890*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zt.GetLaneSizeInBytesLog2() >= msize_in_bytes_log2);
3891*f5c631daSSadaf Ebrahimi   if (is_signed) {
3892*f5c631daSSadaf Ebrahimi     // Sign-extension is only possible when the vector elements are larger than
3893*f5c631daSSadaf Ebrahimi     // the elements in memory.
3894*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zt.GetLaneSizeInBytesLog2() != msize_in_bytes_log2);
3895*f5c631daSSadaf Ebrahimi   }
3896*f5c631daSSadaf Ebrahimi 
3897*f5c631daSSadaf Ebrahimi   if (addr.IsScatterGather()) {
3898*f5c631daSSadaf Ebrahimi     bool is_load = true;
3899*f5c631daSSadaf Ebrahimi     bool is_ff = true;
3900*f5c631daSSadaf Ebrahimi     SVEScatterGatherHelper(msize_in_bytes_log2,
3901*f5c631daSSadaf Ebrahimi                            zt,
3902*f5c631daSSadaf Ebrahimi                            pg,
3903*f5c631daSSadaf Ebrahimi                            addr,
3904*f5c631daSSadaf Ebrahimi                            is_load,
3905*f5c631daSSadaf Ebrahimi                            is_signed,
3906*f5c631daSSadaf Ebrahimi                            is_ff);
3907*f5c631daSSadaf Ebrahimi     return;
3908*f5c631daSSadaf Ebrahimi   }
3909*f5c631daSSadaf Ebrahimi 
3910*f5c631daSSadaf Ebrahimi   if (addr.IsPlainScalar()) {
3911*f5c631daSSadaf Ebrahimi     // SVEMemOperand(x0) is treated as a scalar-plus-immediate form ([x0, #0]).
3912*f5c631daSSadaf Ebrahimi     // In these instructions, we want to treat it as [x0, xzr].
3913*f5c631daSSadaf Ebrahimi     SVEMemOperand addr_scalar_plus_scalar(addr.GetScalarBase(), xzr);
3914*f5c631daSSadaf Ebrahimi     // Guard against infinite recursion.
3915*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(!addr_scalar_plus_scalar.IsPlainScalar());
3916*f5c631daSSadaf Ebrahimi     SVELdff1Helper(msize_in_bytes_log2,
3917*f5c631daSSadaf Ebrahimi                    zt,
3918*f5c631daSSadaf Ebrahimi                    pg,
3919*f5c631daSSadaf Ebrahimi                    addr_scalar_plus_scalar,
3920*f5c631daSSadaf Ebrahimi                    is_signed);
3921*f5c631daSSadaf Ebrahimi     return;
3922*f5c631daSSadaf Ebrahimi   }
3923*f5c631daSSadaf Ebrahimi 
3924*f5c631daSSadaf Ebrahimi   Instr op = 0xffffffff;
3925*f5c631daSSadaf Ebrahimi   if (addr.IsScalarPlusScalar()) {
3926*f5c631daSSadaf Ebrahimi     op = SVEContiguousFirstFaultLoad_ScalarPlusScalarFixed;
3927*f5c631daSSadaf Ebrahimi   } else {
3928*f5c631daSSadaf Ebrahimi     VIXL_UNIMPLEMENTED();
3929*f5c631daSSadaf Ebrahimi   }
3930*f5c631daSSadaf Ebrahimi   SVELdSt1Helper(msize_in_bytes_log2, zt, pg, addr, is_signed, op);
3931*f5c631daSSadaf Ebrahimi }
3932*f5c631daSSadaf Ebrahimi 
SVEScatterGatherHelper(unsigned msize_in_bytes_log2,const ZRegister & zt,const PRegister & pg,const SVEMemOperand & addr,bool is_load,bool is_signed,bool is_first_fault)3933*f5c631daSSadaf Ebrahimi void Assembler::SVEScatterGatherHelper(unsigned msize_in_bytes_log2,
3934*f5c631daSSadaf Ebrahimi                                        const ZRegister& zt,
3935*f5c631daSSadaf Ebrahimi                                        const PRegister& pg,
3936*f5c631daSSadaf Ebrahimi                                        const SVEMemOperand& addr,
3937*f5c631daSSadaf Ebrahimi                                        bool is_load,
3938*f5c631daSSadaf Ebrahimi                                        bool is_signed,
3939*f5c631daSSadaf Ebrahimi                                        bool is_first_fault) {
3940*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsScatterGather());
3941*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zt.IsLaneSizeS() || zt.IsLaneSizeD());
3942*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(is_load || !is_first_fault);
3943*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(is_load || !is_signed);
3944*f5c631daSSadaf Ebrahimi 
3945*f5c631daSSadaf Ebrahimi   Instr op = 0xffffffff;
3946*f5c631daSSadaf Ebrahimi   if (addr.IsVectorPlusImmediate()) {
3947*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(AreSameLaneSize(zt, addr.GetVectorBase()));
3948*f5c631daSSadaf Ebrahimi     if (is_load) {
3949*f5c631daSSadaf Ebrahimi       if (zt.IsLaneSizeS()) {
3950*f5c631daSSadaf Ebrahimi         op = SVE32BitGatherLoad_VectorPlusImmFixed;
3951*f5c631daSSadaf Ebrahimi       } else {
3952*f5c631daSSadaf Ebrahimi         op = SVE64BitGatherLoad_VectorPlusImmFixed;
3953*f5c631daSSadaf Ebrahimi       }
3954*f5c631daSSadaf Ebrahimi     } else {
3955*f5c631daSSadaf Ebrahimi       if (zt.IsLaneSizeS()) {
3956*f5c631daSSadaf Ebrahimi         op = SVE32BitScatterStore_VectorPlusImmFixed;
3957*f5c631daSSadaf Ebrahimi       } else {
3958*f5c631daSSadaf Ebrahimi         op = SVE64BitScatterStore_VectorPlusImmFixed;
3959*f5c631daSSadaf Ebrahimi       }
3960*f5c631daSSadaf Ebrahimi     }
3961*f5c631daSSadaf Ebrahimi   } else {
3962*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(addr.IsScalarPlusVector());
3963*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(AreSameLaneSize(zt, addr.GetVectorOffset()));
3964*f5c631daSSadaf Ebrahimi     SVEOffsetModifier mod = addr.GetOffsetModifier();
3965*f5c631daSSadaf Ebrahimi     if (zt.IsLaneSizeS()) {
3966*f5c631daSSadaf Ebrahimi       VIXL_ASSERT((mod == SVE_UXTW) || (mod == SVE_SXTW));
3967*f5c631daSSadaf Ebrahimi       unsigned shift_amount = addr.GetShiftAmount();
3968*f5c631daSSadaf Ebrahimi       if (shift_amount == 0) {
3969*f5c631daSSadaf Ebrahimi         if (is_load) {
3970*f5c631daSSadaf Ebrahimi           op = SVE32BitGatherLoad_ScalarPlus32BitUnscaledOffsetsFixed;
3971*f5c631daSSadaf Ebrahimi         } else {
3972*f5c631daSSadaf Ebrahimi           op = SVE32BitScatterStore_ScalarPlus32BitUnscaledOffsetsFixed;
3973*f5c631daSSadaf Ebrahimi         }
3974*f5c631daSSadaf Ebrahimi       } else if (shift_amount == 1) {
3975*f5c631daSSadaf Ebrahimi         VIXL_ASSERT(msize_in_bytes_log2 == kHRegSizeInBytesLog2);
3976*f5c631daSSadaf Ebrahimi         if (is_load) {
3977*f5c631daSSadaf Ebrahimi           op = SVE32BitGatherLoadHalfwords_ScalarPlus32BitScaledOffsetsFixed;
3978*f5c631daSSadaf Ebrahimi         } else {
3979*f5c631daSSadaf Ebrahimi           op = SVE32BitScatterStore_ScalarPlus32BitScaledOffsetsFixed;
3980*f5c631daSSadaf Ebrahimi         }
3981*f5c631daSSadaf Ebrahimi       } else {
3982*f5c631daSSadaf Ebrahimi         VIXL_ASSERT(shift_amount == 2);
3983*f5c631daSSadaf Ebrahimi         VIXL_ASSERT(msize_in_bytes_log2 == kSRegSizeInBytesLog2);
3984*f5c631daSSadaf Ebrahimi         if (is_load) {
3985*f5c631daSSadaf Ebrahimi           op = SVE32BitGatherLoadWords_ScalarPlus32BitScaledOffsetsFixed;
3986*f5c631daSSadaf Ebrahimi         } else {
3987*f5c631daSSadaf Ebrahimi           op = SVE32BitScatterStore_ScalarPlus32BitScaledOffsetsFixed;
3988*f5c631daSSadaf Ebrahimi         }
3989*f5c631daSSadaf Ebrahimi       }
3990*f5c631daSSadaf Ebrahimi     } else if (zt.IsLaneSizeD()) {
3991*f5c631daSSadaf Ebrahimi       switch (mod) {
3992*f5c631daSSadaf Ebrahimi         case NO_SVE_OFFSET_MODIFIER:
3993*f5c631daSSadaf Ebrahimi           if (is_load) {
3994*f5c631daSSadaf Ebrahimi             op = SVE64BitGatherLoad_ScalarPlus64BitUnscaledOffsetsFixed;
3995*f5c631daSSadaf Ebrahimi           } else {
3996*f5c631daSSadaf Ebrahimi             op = SVE64BitScatterStore_ScalarPlus64BitUnscaledOffsetsFixed;
3997*f5c631daSSadaf Ebrahimi           }
3998*f5c631daSSadaf Ebrahimi           break;
3999*f5c631daSSadaf Ebrahimi         case SVE_LSL:
4000*f5c631daSSadaf Ebrahimi           if (is_load) {
4001*f5c631daSSadaf Ebrahimi             op = SVE64BitGatherLoad_ScalarPlus64BitScaledOffsetsFixed;
4002*f5c631daSSadaf Ebrahimi           } else {
4003*f5c631daSSadaf Ebrahimi             op = SVE64BitScatterStore_ScalarPlus64BitScaledOffsetsFixed;
4004*f5c631daSSadaf Ebrahimi           }
4005*f5c631daSSadaf Ebrahimi           break;
4006*f5c631daSSadaf Ebrahimi         case SVE_UXTW:
4007*f5c631daSSadaf Ebrahimi         case SVE_SXTW: {
4008*f5c631daSSadaf Ebrahimi           unsigned shift_amount = addr.GetShiftAmount();
4009*f5c631daSSadaf Ebrahimi           if (shift_amount == 0) {
4010*f5c631daSSadaf Ebrahimi             if (is_load) {
4011*f5c631daSSadaf Ebrahimi               op =
4012*f5c631daSSadaf Ebrahimi                   SVE64BitGatherLoad_ScalarPlusUnpacked32BitUnscaledOffsetsFixed;
4013*f5c631daSSadaf Ebrahimi             } else {
4014*f5c631daSSadaf Ebrahimi               op =
4015*f5c631daSSadaf Ebrahimi                   SVE64BitScatterStore_ScalarPlusUnpacked32BitUnscaledOffsetsFixed;
4016*f5c631daSSadaf Ebrahimi             }
4017*f5c631daSSadaf Ebrahimi           } else {
4018*f5c631daSSadaf Ebrahimi             VIXL_ASSERT(shift_amount == msize_in_bytes_log2);
4019*f5c631daSSadaf Ebrahimi             if (is_load) {
4020*f5c631daSSadaf Ebrahimi               op = SVE64BitGatherLoad_ScalarPlus32BitUnpackedScaledOffsetsFixed;
4021*f5c631daSSadaf Ebrahimi             } else {
4022*f5c631daSSadaf Ebrahimi               op =
4023*f5c631daSSadaf Ebrahimi                   SVE64BitScatterStore_ScalarPlusUnpacked32BitScaledOffsetsFixed;
4024*f5c631daSSadaf Ebrahimi             }
4025*f5c631daSSadaf Ebrahimi           }
4026*f5c631daSSadaf Ebrahimi           break;
4027*f5c631daSSadaf Ebrahimi         }
4028*f5c631daSSadaf Ebrahimi         default:
4029*f5c631daSSadaf Ebrahimi           VIXL_UNIMPLEMENTED();
4030*f5c631daSSadaf Ebrahimi       }
4031*f5c631daSSadaf Ebrahimi     }
4032*f5c631daSSadaf Ebrahimi   }
4033*f5c631daSSadaf Ebrahimi 
4034*f5c631daSSadaf Ebrahimi   Instr mem_op = SVEMemOperandHelper(msize_in_bytes_log2, 1, addr, is_load);
4035*f5c631daSSadaf Ebrahimi   Instr msz = ImmUnsignedField<24, 23>(msize_in_bytes_log2);
4036*f5c631daSSadaf Ebrahimi   Instr u = (!is_load || is_signed) ? 0 : (1 << 14);
4037*f5c631daSSadaf Ebrahimi   Instr ff = is_first_fault ? (1 << 13) : 0;
4038*f5c631daSSadaf Ebrahimi   Emit(op | mem_op | msz | u | ff | Rt(zt) | PgLow8(pg));
4039*f5c631daSSadaf Ebrahimi }
4040*f5c631daSSadaf Ebrahimi 
SVELd234Helper(int num_regs,const ZRegister & zt1,const PRegisterZ & pg,const SVEMemOperand & addr)4041*f5c631daSSadaf Ebrahimi void Assembler::SVELd234Helper(int num_regs,
4042*f5c631daSSadaf Ebrahimi                                const ZRegister& zt1,
4043*f5c631daSSadaf Ebrahimi                                const PRegisterZ& pg,
4044*f5c631daSSadaf Ebrahimi                                const SVEMemOperand& addr) {
4045*f5c631daSSadaf Ebrahimi   if (addr.IsScalarPlusScalar()) {
4046*f5c631daSSadaf Ebrahimi     // Rm must not be xzr.
4047*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(!addr.GetScalarOffset().IsZero());
4048*f5c631daSSadaf Ebrahimi   }
4049*f5c631daSSadaf Ebrahimi 
4050*f5c631daSSadaf Ebrahimi   Instr op;
4051*f5c631daSSadaf Ebrahimi   if (addr.IsScalarPlusImmediate()) {
4052*f5c631daSSadaf Ebrahimi     op = SVELoadMultipleStructures_ScalarPlusImmFixed;
4053*f5c631daSSadaf Ebrahimi   } else if (addr.IsScalarPlusScalar()) {
4054*f5c631daSSadaf Ebrahimi     op = SVELoadMultipleStructures_ScalarPlusScalarFixed;
4055*f5c631daSSadaf Ebrahimi   } else {
4056*f5c631daSSadaf Ebrahimi     // These instructions don't support any other addressing modes.
4057*f5c631daSSadaf Ebrahimi     VIXL_ABORT();
4058*f5c631daSSadaf Ebrahimi   }
4059*f5c631daSSadaf Ebrahimi   SVELdSt234Helper(num_regs, zt1, pg, addr, op);
4060*f5c631daSSadaf Ebrahimi }
4061*f5c631daSSadaf Ebrahimi 
4062*f5c631daSSadaf Ebrahimi // SVEMemContiguousLoad.
4063*f5c631daSSadaf Ebrahimi 
4064*f5c631daSSadaf Ebrahimi #define VIXL_DEFINE_LD1(MSZ, LANE_SIZE)                                  \
4065*f5c631daSSadaf Ebrahimi   void Assembler::ld1##MSZ(const ZRegister& zt,                          \
4066*f5c631daSSadaf Ebrahimi                            const PRegisterZ& pg,                         \
4067*f5c631daSSadaf Ebrahimi                            const SVEMemOperand& addr) {                  \
4068*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));                              \
4069*f5c631daSSadaf Ebrahimi     SVELd1Helper(k##LANE_SIZE##RegSizeInBytesLog2, zt, pg, addr, false); \
4070*f5c631daSSadaf Ebrahimi   }
4071*f5c631daSSadaf Ebrahimi #define VIXL_DEFINE_LD2(MSZ, LANE_SIZE)                 \
4072*f5c631daSSadaf Ebrahimi   void Assembler::ld2##MSZ(const ZRegister& zt1,        \
4073*f5c631daSSadaf Ebrahimi                            const ZRegister& zt2,        \
4074*f5c631daSSadaf Ebrahimi                            const PRegisterZ& pg,        \
4075*f5c631daSSadaf Ebrahimi                            const SVEMemOperand& addr) { \
4076*f5c631daSSadaf Ebrahimi     USE(zt2);                                           \
4077*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));             \
4078*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(AreConsecutive(zt1, zt2));              \
4079*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(AreSameFormat(zt1, zt2));               \
4080*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zt1.IsLaneSize##LANE_SIZE());           \
4081*f5c631daSSadaf Ebrahimi     SVELd234Helper(2, zt1, pg, addr);                   \
4082*f5c631daSSadaf Ebrahimi   }
4083*f5c631daSSadaf Ebrahimi #define VIXL_DEFINE_LD3(MSZ, LANE_SIZE)                 \
4084*f5c631daSSadaf Ebrahimi   void Assembler::ld3##MSZ(const ZRegister& zt1,        \
4085*f5c631daSSadaf Ebrahimi                            const ZRegister& zt2,        \
4086*f5c631daSSadaf Ebrahimi                            const ZRegister& zt3,        \
4087*f5c631daSSadaf Ebrahimi                            const PRegisterZ& pg,        \
4088*f5c631daSSadaf Ebrahimi                            const SVEMemOperand& addr) { \
4089*f5c631daSSadaf Ebrahimi     USE(zt2, zt3);                                      \
4090*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));             \
4091*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(AreConsecutive(zt1, zt2, zt3));         \
4092*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(AreSameFormat(zt1, zt2, zt3));          \
4093*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zt1.IsLaneSize##LANE_SIZE());           \
4094*f5c631daSSadaf Ebrahimi     SVELd234Helper(3, zt1, pg, addr);                   \
4095*f5c631daSSadaf Ebrahimi   }
4096*f5c631daSSadaf Ebrahimi #define VIXL_DEFINE_LD4(MSZ, LANE_SIZE)                 \
4097*f5c631daSSadaf Ebrahimi   void Assembler::ld4##MSZ(const ZRegister& zt1,        \
4098*f5c631daSSadaf Ebrahimi                            const ZRegister& zt2,        \
4099*f5c631daSSadaf Ebrahimi                            const ZRegister& zt3,        \
4100*f5c631daSSadaf Ebrahimi                            const ZRegister& zt4,        \
4101*f5c631daSSadaf Ebrahimi                            const PRegisterZ& pg,        \
4102*f5c631daSSadaf Ebrahimi                            const SVEMemOperand& addr) { \
4103*f5c631daSSadaf Ebrahimi     USE(zt2, zt3, zt4);                                 \
4104*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));             \
4105*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(AreConsecutive(zt1, zt2, zt3, zt4));    \
4106*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(AreSameFormat(zt1, zt2, zt3, zt4));     \
4107*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zt1.IsLaneSize##LANE_SIZE());           \
4108*f5c631daSSadaf Ebrahimi     SVELd234Helper(4, zt1, pg, addr);                   \
4109*f5c631daSSadaf Ebrahimi   }
4110*f5c631daSSadaf Ebrahimi 
4111*f5c631daSSadaf Ebrahimi VIXL_SVE_LOAD_STORE_VARIANT_LIST(VIXL_DEFINE_LD1)
VIXL_SVE_LOAD_STORE_VARIANT_LIST(VIXL_DEFINE_LD2)4112*f5c631daSSadaf Ebrahimi VIXL_SVE_LOAD_STORE_VARIANT_LIST(VIXL_DEFINE_LD2)
4113*f5c631daSSadaf Ebrahimi VIXL_SVE_LOAD_STORE_VARIANT_LIST(VIXL_DEFINE_LD3)
4114*f5c631daSSadaf Ebrahimi VIXL_SVE_LOAD_STORE_VARIANT_LIST(VIXL_DEFINE_LD4)
4115*f5c631daSSadaf Ebrahimi 
4116*f5c631daSSadaf Ebrahimi #define VIXL_DEFINE_LD1S(MSZ, LANE_SIZE)                                \
4117*f5c631daSSadaf Ebrahimi   void Assembler::ld1s##MSZ(const ZRegister& zt,                        \
4118*f5c631daSSadaf Ebrahimi                             const PRegisterZ& pg,                       \
4119*f5c631daSSadaf Ebrahimi                             const SVEMemOperand& addr) {                \
4120*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));                             \
4121*f5c631daSSadaf Ebrahimi     SVELd1Helper(k##LANE_SIZE##RegSizeInBytesLog2, zt, pg, addr, true); \
4122*f5c631daSSadaf Ebrahimi   }
4123*f5c631daSSadaf Ebrahimi VIXL_SVE_LOAD_STORE_SIGNED_VARIANT_LIST(VIXL_DEFINE_LD1S)
4124*f5c631daSSadaf Ebrahimi 
4125*f5c631daSSadaf Ebrahimi // SVEMem32BitGatherAndUnsizedContiguous.
4126*f5c631daSSadaf Ebrahimi 
4127*f5c631daSSadaf Ebrahimi void Assembler::SVELd1BroadcastHelper(unsigned msize_in_bytes_log2,
4128*f5c631daSSadaf Ebrahimi                                       const ZRegister& zt,
4129*f5c631daSSadaf Ebrahimi                                       const PRegisterZ& pg,
4130*f5c631daSSadaf Ebrahimi                                       const SVEMemOperand& addr,
4131*f5c631daSSadaf Ebrahimi                                       bool is_signed) {
4132*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsScalarPlusImmediate());
4133*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zt.GetLaneSizeInBytesLog2() >= msize_in_bytes_log2);
4134*f5c631daSSadaf Ebrahimi   if (is_signed) {
4135*f5c631daSSadaf Ebrahimi     // Sign-extension is only possible when the vector elements are larger than
4136*f5c631daSSadaf Ebrahimi     // the elements in memory.
4137*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zt.GetLaneSizeInBytesLog2() != msize_in_bytes_log2);
4138*f5c631daSSadaf Ebrahimi   }
4139*f5c631daSSadaf Ebrahimi 
4140*f5c631daSSadaf Ebrahimi   int64_t imm = addr.GetImmediateOffset();
4141*f5c631daSSadaf Ebrahimi   int divisor = 1 << msize_in_bytes_log2;
4142*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(imm % divisor == 0);
4143*f5c631daSSadaf Ebrahimi   Instr dtype = SVEDtypeSplit(msize_in_bytes_log2,
4144*f5c631daSSadaf Ebrahimi                               zt.GetLaneSizeInBytesLog2(),
4145*f5c631daSSadaf Ebrahimi                               is_signed);
4146*f5c631daSSadaf Ebrahimi 
4147*f5c631daSSadaf Ebrahimi   Emit(SVELoadAndBroadcastElementFixed | dtype | RnSP(addr.GetScalarBase()) |
4148*f5c631daSSadaf Ebrahimi        ImmUnsignedField<21, 16>(imm / divisor) | Rt(zt) | PgLow8(pg));
4149*f5c631daSSadaf Ebrahimi }
4150*f5c631daSSadaf Ebrahimi 
4151*f5c631daSSadaf Ebrahimi // This prototype maps to 4 instruction encodings:
4152*f5c631daSSadaf Ebrahimi //  LD1RB_z_p_bi_u16
4153*f5c631daSSadaf Ebrahimi //  LD1RB_z_p_bi_u32
4154*f5c631daSSadaf Ebrahimi //  LD1RB_z_p_bi_u64
4155*f5c631daSSadaf Ebrahimi //  LD1RB_z_p_bi_u8
ld1rb(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)4156*f5c631daSSadaf Ebrahimi void Assembler::ld1rb(const ZRegister& zt,
4157*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
4158*f5c631daSSadaf Ebrahimi                       const SVEMemOperand& addr) {
4159*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4160*f5c631daSSadaf Ebrahimi 
4161*f5c631daSSadaf Ebrahimi   SVELd1BroadcastHelper(kBRegSizeInBytesLog2, zt, pg, addr, false);
4162*f5c631daSSadaf Ebrahimi }
4163*f5c631daSSadaf Ebrahimi 
4164*f5c631daSSadaf Ebrahimi // This prototype maps to 3 instruction encodings:
4165*f5c631daSSadaf Ebrahimi //  LD1RH_z_p_bi_u16
4166*f5c631daSSadaf Ebrahimi //  LD1RH_z_p_bi_u32
4167*f5c631daSSadaf Ebrahimi //  LD1RH_z_p_bi_u64
ld1rh(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)4168*f5c631daSSadaf Ebrahimi void Assembler::ld1rh(const ZRegister& zt,
4169*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
4170*f5c631daSSadaf Ebrahimi                       const SVEMemOperand& addr) {
4171*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4172*f5c631daSSadaf Ebrahimi 
4173*f5c631daSSadaf Ebrahimi   SVELd1BroadcastHelper(kHRegSizeInBytesLog2, zt, pg, addr, false);
4174*f5c631daSSadaf Ebrahimi }
4175*f5c631daSSadaf Ebrahimi 
4176*f5c631daSSadaf Ebrahimi // This prototype maps to 2 instruction encodings:
4177*f5c631daSSadaf Ebrahimi //  LD1RW_z_p_bi_u32
4178*f5c631daSSadaf Ebrahimi //  LD1RW_z_p_bi_u64
ld1rw(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)4179*f5c631daSSadaf Ebrahimi void Assembler::ld1rw(const ZRegister& zt,
4180*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
4181*f5c631daSSadaf Ebrahimi                       const SVEMemOperand& addr) {
4182*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4183*f5c631daSSadaf Ebrahimi 
4184*f5c631daSSadaf Ebrahimi   SVELd1BroadcastHelper(kSRegSizeInBytesLog2, zt, pg, addr, false);
4185*f5c631daSSadaf Ebrahimi }
4186*f5c631daSSadaf Ebrahimi 
ld1rd(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)4187*f5c631daSSadaf Ebrahimi void Assembler::ld1rd(const ZRegister& zt,
4188*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
4189*f5c631daSSadaf Ebrahimi                       const SVEMemOperand& addr) {
4190*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4191*f5c631daSSadaf Ebrahimi 
4192*f5c631daSSadaf Ebrahimi   SVELd1BroadcastHelper(kDRegSizeInBytesLog2, zt, pg, addr, false);
4193*f5c631daSSadaf Ebrahimi }
4194*f5c631daSSadaf Ebrahimi 
4195*f5c631daSSadaf Ebrahimi // This prototype maps to 3 instruction encodings:
4196*f5c631daSSadaf Ebrahimi //  LD1RSB_z_p_bi_s16
4197*f5c631daSSadaf Ebrahimi //  LD1RSB_z_p_bi_s32
4198*f5c631daSSadaf Ebrahimi //  LD1RSB_z_p_bi_s64
ld1rsb(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)4199*f5c631daSSadaf Ebrahimi void Assembler::ld1rsb(const ZRegister& zt,
4200*f5c631daSSadaf Ebrahimi                        const PRegisterZ& pg,
4201*f5c631daSSadaf Ebrahimi                        const SVEMemOperand& addr) {
4202*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4203*f5c631daSSadaf Ebrahimi 
4204*f5c631daSSadaf Ebrahimi   SVELd1BroadcastHelper(kBRegSizeInBytesLog2, zt, pg, addr, true);
4205*f5c631daSSadaf Ebrahimi }
4206*f5c631daSSadaf Ebrahimi 
4207*f5c631daSSadaf Ebrahimi // This prototype maps to 2 instruction encodings:
4208*f5c631daSSadaf Ebrahimi //  LD1RSH_z_p_bi_s32
4209*f5c631daSSadaf Ebrahimi //  LD1RSH_z_p_bi_s64
ld1rsh(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)4210*f5c631daSSadaf Ebrahimi void Assembler::ld1rsh(const ZRegister& zt,
4211*f5c631daSSadaf Ebrahimi                        const PRegisterZ& pg,
4212*f5c631daSSadaf Ebrahimi                        const SVEMemOperand& addr) {
4213*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4214*f5c631daSSadaf Ebrahimi 
4215*f5c631daSSadaf Ebrahimi   SVELd1BroadcastHelper(kHRegSizeInBytesLog2, zt, pg, addr, true);
4216*f5c631daSSadaf Ebrahimi }
4217*f5c631daSSadaf Ebrahimi 
ld1rsw(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)4218*f5c631daSSadaf Ebrahimi void Assembler::ld1rsw(const ZRegister& zt,
4219*f5c631daSSadaf Ebrahimi                        const PRegisterZ& pg,
4220*f5c631daSSadaf Ebrahimi                        const SVEMemOperand& addr) {
4221*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4222*f5c631daSSadaf Ebrahimi 
4223*f5c631daSSadaf Ebrahimi   SVELd1BroadcastHelper(kWRegSizeInBytesLog2, zt, pg, addr, true);
4224*f5c631daSSadaf Ebrahimi }
4225*f5c631daSSadaf Ebrahimi 
ldr(const CPURegister & rt,const SVEMemOperand & addr)4226*f5c631daSSadaf Ebrahimi void Assembler::ldr(const CPURegister& rt, const SVEMemOperand& addr) {
4227*f5c631daSSadaf Ebrahimi   // LDR <Pt/Zt>, [<Xn|SP>{, #<imm>, MUL VL}]
4228*f5c631daSSadaf Ebrahimi 
4229*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4230*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(rt.IsPRegister() || rt.IsZRegister());
4231*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsPlainScalar() ||
4232*f5c631daSSadaf Ebrahimi               (addr.IsScalarPlusImmediate() &&
4233*f5c631daSSadaf Ebrahimi                (addr.GetOffsetModifier() == SVE_MUL_VL)));
4234*f5c631daSSadaf Ebrahimi   int64_t imm9 = addr.GetImmediateOffset();
4235*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(IsInt9(imm9));
4236*f5c631daSSadaf Ebrahimi   Instr imm9l = ExtractUnsignedBitfield32(2, 0, imm9) << 10;
4237*f5c631daSSadaf Ebrahimi   Instr imm9h = ExtractUnsignedBitfield32(8, 3, imm9) << 16;
4238*f5c631daSSadaf Ebrahimi 
4239*f5c631daSSadaf Ebrahimi   Instr op = LDR_z_bi;
4240*f5c631daSSadaf Ebrahimi   if (rt.IsPRegister()) {
4241*f5c631daSSadaf Ebrahimi     op = LDR_p_bi;
4242*f5c631daSSadaf Ebrahimi   }
4243*f5c631daSSadaf Ebrahimi   Emit(op | Rt(rt) | RnSP(addr.GetScalarBase()) | imm9h | imm9l);
4244*f5c631daSSadaf Ebrahimi }
4245*f5c631daSSadaf Ebrahimi 
4246*f5c631daSSadaf Ebrahimi // SVEMem64BitGather.
4247*f5c631daSSadaf Ebrahimi 
4248*f5c631daSSadaf Ebrahimi // This prototype maps to 3 instruction encodings:
4249*f5c631daSSadaf Ebrahimi //  LDFF1B_z_p_bz_d_64_unscaled
4250*f5c631daSSadaf Ebrahimi //  LDFF1B_z_p_bz_d_x32_unscaled
ldff1b(const ZRegister & zt,const PRegisterZ & pg,const Register & xn,const ZRegister & zm)4251*f5c631daSSadaf Ebrahimi void Assembler::ldff1b(const ZRegister& zt,
4252*f5c631daSSadaf Ebrahimi                        const PRegisterZ& pg,
4253*f5c631daSSadaf Ebrahimi                        const Register& xn,
4254*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
4255*f5c631daSSadaf Ebrahimi   // LDFF1B { <Zt>.D }, <Pg>/Z, [<Xn|SP>, <Zm>.D]
4256*f5c631daSSadaf Ebrahimi   //  1100 0100 010. .... 111. .... .... ....
4257*f5c631daSSadaf Ebrahimi   //  msz<24:23> = 00 | Zm<20:16> | U<14> = 1 | ff<13> = 1 | Pg<12:10> | Rn<9:5>
4258*f5c631daSSadaf Ebrahimi   //  | Zt<4:0>
4259*f5c631daSSadaf Ebrahimi 
4260*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4261*f5c631daSSadaf Ebrahimi 
4262*f5c631daSSadaf Ebrahimi   Emit(LDFF1B_z_p_bz_d_64_unscaled | Rt(zt) | PgLow8(pg) | RnSP(xn) | Rm(zm));
4263*f5c631daSSadaf Ebrahimi }
4264*f5c631daSSadaf Ebrahimi 
4265*f5c631daSSadaf Ebrahimi // This prototype maps to 2 instruction encodings:
4266*f5c631daSSadaf Ebrahimi //  LDFF1B_z_p_ai_d
4267*f5c631daSSadaf Ebrahimi //  LDFF1B_z_p_ai_s
ldff1b(const ZRegister & zt,const PRegisterZ & pg,const ZRegister & zn,int imm5)4268*f5c631daSSadaf Ebrahimi void Assembler::ldff1b(const ZRegister& zt,
4269*f5c631daSSadaf Ebrahimi                        const PRegisterZ& pg,
4270*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
4271*f5c631daSSadaf Ebrahimi                        int imm5) {
4272*f5c631daSSadaf Ebrahimi   // LDFF1B { <Zt>.D }, <Pg>/Z, [<Zn>.D{, #<imm>}]
4273*f5c631daSSadaf Ebrahimi   //  1100 0100 001. .... 111. .... .... ....
4274*f5c631daSSadaf Ebrahimi   //  msz<24:23> = 00 | imm5<20:16> | U<14> = 1 | ff<13> = 1 | Pg<12:10> |
4275*f5c631daSSadaf Ebrahimi   //  Zn<9:5> | Zt<4:0>
4276*f5c631daSSadaf Ebrahimi 
4277*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4278*f5c631daSSadaf Ebrahimi 
4279*f5c631daSSadaf Ebrahimi   Emit(LDFF1B_z_p_ai_d | Rt(zt) | PgLow8(pg) | Rn(zn) | ImmField<20, 16>(imm5));
4280*f5c631daSSadaf Ebrahimi }
4281*f5c631daSSadaf Ebrahimi 
4282*f5c631daSSadaf Ebrahimi // This prototype maps to 4 instruction encodings:
4283*f5c631daSSadaf Ebrahimi //  LDFF1D_z_p_bz_d_64_scaled
4284*f5c631daSSadaf Ebrahimi //  LDFF1D_z_p_bz_d_64_unscaled
4285*f5c631daSSadaf Ebrahimi //  LDFF1D_z_p_bz_d_x32_scaled
4286*f5c631daSSadaf Ebrahimi //  LDFF1D_z_p_bz_d_x32_unscaled
ldff1d(const ZRegister & zt,const PRegisterZ & pg,const Register & xn,const ZRegister & zm)4287*f5c631daSSadaf Ebrahimi void Assembler::ldff1d(const ZRegister& zt,
4288*f5c631daSSadaf Ebrahimi                        const PRegisterZ& pg,
4289*f5c631daSSadaf Ebrahimi                        const Register& xn,
4290*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
4291*f5c631daSSadaf Ebrahimi   // LDFF1D { <Zt>.D }, <Pg>/Z, [<Xn|SP>, <Zm>.D, LSL #3]
4292*f5c631daSSadaf Ebrahimi   //  1100 0101 111. .... 111. .... .... ....
4293*f5c631daSSadaf Ebrahimi   //  msz<24:23> = 11 | Zm<20:16> | U<14> = 1 | ff<13> = 1 | Pg<12:10> | Rn<9:5>
4294*f5c631daSSadaf Ebrahimi   //  | Zt<4:0>
4295*f5c631daSSadaf Ebrahimi 
4296*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4297*f5c631daSSadaf Ebrahimi 
4298*f5c631daSSadaf Ebrahimi   Emit(LDFF1D_z_p_bz_d_64_scaled | Rt(zt) | PgLow8(pg) | RnSP(xn) | Rm(zm));
4299*f5c631daSSadaf Ebrahimi }
4300*f5c631daSSadaf Ebrahimi 
ldff1d(const ZRegister & zt,const PRegisterZ & pg,const ZRegister & zn,int imm5)4301*f5c631daSSadaf Ebrahimi void Assembler::ldff1d(const ZRegister& zt,
4302*f5c631daSSadaf Ebrahimi                        const PRegisterZ& pg,
4303*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
4304*f5c631daSSadaf Ebrahimi                        int imm5) {
4305*f5c631daSSadaf Ebrahimi   // LDFF1D { <Zt>.D }, <Pg>/Z, [<Zn>.D{, #<imm>}]
4306*f5c631daSSadaf Ebrahimi   //  1100 0101 101. .... 111. .... .... ....
4307*f5c631daSSadaf Ebrahimi   //  msz<24:23> = 11 | imm5<20:16> | U<14> = 1 | ff<13> = 1 | Pg<12:10> |
4308*f5c631daSSadaf Ebrahimi   //  Zn<9:5> | Zt<4:0>
4309*f5c631daSSadaf Ebrahimi 
4310*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4311*f5c631daSSadaf Ebrahimi 
4312*f5c631daSSadaf Ebrahimi   Emit(LDFF1D_z_p_ai_d | Rt(zt) | PgLow8(pg) | Rn(zn) | ImmField<20, 16>(imm5));
4313*f5c631daSSadaf Ebrahimi }
4314*f5c631daSSadaf Ebrahimi 
4315*f5c631daSSadaf Ebrahimi // This prototype maps to 6 instruction encodings:
4316*f5c631daSSadaf Ebrahimi //  LDFF1H_z_p_bz_d_64_scaled
4317*f5c631daSSadaf Ebrahimi //  LDFF1H_z_p_bz_d_64_unscaled
4318*f5c631daSSadaf Ebrahimi //  LDFF1H_z_p_bz_d_x32_scaled
4319*f5c631daSSadaf Ebrahimi //  LDFF1H_z_p_bz_d_x32_unscaled
ldff1h(const ZRegister & zt,const PRegisterZ & pg,const Register & xn,const ZRegister & zm)4320*f5c631daSSadaf Ebrahimi void Assembler::ldff1h(const ZRegister& zt,
4321*f5c631daSSadaf Ebrahimi                        const PRegisterZ& pg,
4322*f5c631daSSadaf Ebrahimi                        const Register& xn,
4323*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
4324*f5c631daSSadaf Ebrahimi   // LDFF1H { <Zt>.D }, <Pg>/Z, [<Xn|SP>, <Zm>.D, LSL #1]
4325*f5c631daSSadaf Ebrahimi   //  1100 0100 111. .... 111. .... .... ....
4326*f5c631daSSadaf Ebrahimi   //  msz<24:23> = 01 | Zm<20:16> | U<14> = 1 | ff<13> = 1 | Pg<12:10> | Rn<9:5>
4327*f5c631daSSadaf Ebrahimi   //  | Zt<4:0>
4328*f5c631daSSadaf Ebrahimi 
4329*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4330*f5c631daSSadaf Ebrahimi 
4331*f5c631daSSadaf Ebrahimi   Emit(LDFF1H_z_p_bz_d_64_scaled | Rt(zt) | PgLow8(pg) | RnSP(xn) | Rm(zm));
4332*f5c631daSSadaf Ebrahimi }
4333*f5c631daSSadaf Ebrahimi 
4334*f5c631daSSadaf Ebrahimi // This prototype maps to 2 instruction encodings:
4335*f5c631daSSadaf Ebrahimi //  LDFF1H_z_p_ai_d
4336*f5c631daSSadaf Ebrahimi //  LDFF1H_z_p_ai_s
ldff1h(const ZRegister & zt,const PRegisterZ & pg,const ZRegister & zn,int imm5)4337*f5c631daSSadaf Ebrahimi void Assembler::ldff1h(const ZRegister& zt,
4338*f5c631daSSadaf Ebrahimi                        const PRegisterZ& pg,
4339*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
4340*f5c631daSSadaf Ebrahimi                        int imm5) {
4341*f5c631daSSadaf Ebrahimi   // LDFF1H { <Zt>.D }, <Pg>/Z, [<Zn>.D{, #<imm>}]
4342*f5c631daSSadaf Ebrahimi   //  1100 0100 101. .... 111. .... .... ....
4343*f5c631daSSadaf Ebrahimi   //  msz<24:23> = 01 | imm5<20:16> | U<14> = 1 | ff<13> = 1 | Pg<12:10> |
4344*f5c631daSSadaf Ebrahimi   //  Zn<9:5> | Zt<4:0>
4345*f5c631daSSadaf Ebrahimi 
4346*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4347*f5c631daSSadaf Ebrahimi 
4348*f5c631daSSadaf Ebrahimi   Emit(LDFF1H_z_p_ai_d | Rt(zt) | PgLow8(pg) | Rn(zn) | ImmField<20, 16>(imm5));
4349*f5c631daSSadaf Ebrahimi }
4350*f5c631daSSadaf Ebrahimi 
4351*f5c631daSSadaf Ebrahimi // This prototype maps to 3 instruction encodings:
4352*f5c631daSSadaf Ebrahimi //  LDFF1SB_z_p_bz_d_64_unscaled
4353*f5c631daSSadaf Ebrahimi //  LDFF1SB_z_p_bz_d_x32_unscaled
ldff1sb(const ZRegister & zt,const PRegisterZ & pg,const Register & xn,const ZRegister & zm)4354*f5c631daSSadaf Ebrahimi void Assembler::ldff1sb(const ZRegister& zt,
4355*f5c631daSSadaf Ebrahimi                         const PRegisterZ& pg,
4356*f5c631daSSadaf Ebrahimi                         const Register& xn,
4357*f5c631daSSadaf Ebrahimi                         const ZRegister& zm) {
4358*f5c631daSSadaf Ebrahimi   // LDFF1SB { <Zt>.D }, <Pg>/Z, [<Xn|SP>, <Zm>.D]
4359*f5c631daSSadaf Ebrahimi   //  1100 0100 010. .... 101. .... .... ....
4360*f5c631daSSadaf Ebrahimi   //  msz<24:23> = 00 | Zm<20:16> | U<14> = 0 | ff<13> = 1 | Pg<12:10> | Rn<9:5>
4361*f5c631daSSadaf Ebrahimi   //  | Zt<4:0>
4362*f5c631daSSadaf Ebrahimi 
4363*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4364*f5c631daSSadaf Ebrahimi 
4365*f5c631daSSadaf Ebrahimi   Emit(LDFF1SB_z_p_bz_d_64_unscaled | Rt(zt) | PgLow8(pg) | RnSP(xn) | Rm(zm));
4366*f5c631daSSadaf Ebrahimi }
4367*f5c631daSSadaf Ebrahimi 
4368*f5c631daSSadaf Ebrahimi // This prototype maps to 2 instruction encodings:
4369*f5c631daSSadaf Ebrahimi //  LDFF1SB_z_p_ai_d
4370*f5c631daSSadaf Ebrahimi //  LDFF1SB_z_p_ai_s
ldff1sb(const ZRegister & zt,const PRegisterZ & pg,const ZRegister & zn,int imm5)4371*f5c631daSSadaf Ebrahimi void Assembler::ldff1sb(const ZRegister& zt,
4372*f5c631daSSadaf Ebrahimi                         const PRegisterZ& pg,
4373*f5c631daSSadaf Ebrahimi                         const ZRegister& zn,
4374*f5c631daSSadaf Ebrahimi                         int imm5) {
4375*f5c631daSSadaf Ebrahimi   // LDFF1SB { <Zt>.D }, <Pg>/Z, [<Zn>.D{, #<imm>}]
4376*f5c631daSSadaf Ebrahimi   //  1100 0100 001. .... 101. .... .... ....
4377*f5c631daSSadaf Ebrahimi   //  msz<24:23> = 00 | imm5<20:16> | U<14> = 0 | ff<13> = 1 | Pg<12:10> |
4378*f5c631daSSadaf Ebrahimi   //  Zn<9:5> | Zt<4:0>
4379*f5c631daSSadaf Ebrahimi 
4380*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4381*f5c631daSSadaf Ebrahimi 
4382*f5c631daSSadaf Ebrahimi   Emit(LDFF1SB_z_p_ai_d | Rt(zt) | PgLow8(pg) | Rn(zn) |
4383*f5c631daSSadaf Ebrahimi        ImmField<20, 16>(imm5));
4384*f5c631daSSadaf Ebrahimi }
4385*f5c631daSSadaf Ebrahimi 
4386*f5c631daSSadaf Ebrahimi // This prototype maps to 6 instruction encodings:
4387*f5c631daSSadaf Ebrahimi //  LDFF1SH_z_p_bz_d_64_scaled
4388*f5c631daSSadaf Ebrahimi //  LDFF1SH_z_p_bz_d_64_unscaled
4389*f5c631daSSadaf Ebrahimi //  LDFF1SH_z_p_bz_d_x32_scaled
4390*f5c631daSSadaf Ebrahimi //  LDFF1SH_z_p_bz_d_x32_unscaled
ldff1sh(const ZRegister & zt,const PRegisterZ & pg,const Register & xn,const ZRegister & zm)4391*f5c631daSSadaf Ebrahimi void Assembler::ldff1sh(const ZRegister& zt,
4392*f5c631daSSadaf Ebrahimi                         const PRegisterZ& pg,
4393*f5c631daSSadaf Ebrahimi                         const Register& xn,
4394*f5c631daSSadaf Ebrahimi                         const ZRegister& zm) {
4395*f5c631daSSadaf Ebrahimi   // LDFF1SH { <Zt>.D }, <Pg>/Z, [<Xn|SP>, <Zm>.D, LSL #1]
4396*f5c631daSSadaf Ebrahimi   //  1100 0100 111. .... 101. .... .... ....
4397*f5c631daSSadaf Ebrahimi   //  msz<24:23> = 01 | Zm<20:16> | U<14> = 0 | ff<13> = 1 | Pg<12:10> | Rn<9:5>
4398*f5c631daSSadaf Ebrahimi   //  | Zt<4:0>
4399*f5c631daSSadaf Ebrahimi 
4400*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4401*f5c631daSSadaf Ebrahimi 
4402*f5c631daSSadaf Ebrahimi   Emit(LDFF1SH_z_p_bz_d_64_scaled | Rt(zt) | PgLow8(pg) | RnSP(xn) | Rm(zm));
4403*f5c631daSSadaf Ebrahimi }
4404*f5c631daSSadaf Ebrahimi 
4405*f5c631daSSadaf Ebrahimi // This prototype maps to 2 instruction encodings:
4406*f5c631daSSadaf Ebrahimi //  LDFF1SH_z_p_ai_d
4407*f5c631daSSadaf Ebrahimi //  LDFF1SH_z_p_ai_s
ldff1sh(const ZRegister & zt,const PRegisterZ & pg,const ZRegister & zn,int imm5)4408*f5c631daSSadaf Ebrahimi void Assembler::ldff1sh(const ZRegister& zt,
4409*f5c631daSSadaf Ebrahimi                         const PRegisterZ& pg,
4410*f5c631daSSadaf Ebrahimi                         const ZRegister& zn,
4411*f5c631daSSadaf Ebrahimi                         int imm5) {
4412*f5c631daSSadaf Ebrahimi   // LDFF1SH { <Zt>.D }, <Pg>/Z, [<Zn>.D{, #<imm>}]
4413*f5c631daSSadaf Ebrahimi   //  1100 0100 101. .... 101. .... .... ....
4414*f5c631daSSadaf Ebrahimi   //  msz<24:23> = 01 | imm5<20:16> | U<14> = 0 | ff<13> = 1 | Pg<12:10> |
4415*f5c631daSSadaf Ebrahimi   //  Zn<9:5> | Zt<4:0>
4416*f5c631daSSadaf Ebrahimi 
4417*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4418*f5c631daSSadaf Ebrahimi 
4419*f5c631daSSadaf Ebrahimi   Emit(LDFF1SH_z_p_ai_d | Rt(zt) | PgLow8(pg) | Rn(zn) |
4420*f5c631daSSadaf Ebrahimi        ImmField<20, 16>(imm5));
4421*f5c631daSSadaf Ebrahimi }
4422*f5c631daSSadaf Ebrahimi 
4423*f5c631daSSadaf Ebrahimi // This prototype maps to 4 instruction encodings:
4424*f5c631daSSadaf Ebrahimi //  LDFF1SW_z_p_bz_d_64_scaled
4425*f5c631daSSadaf Ebrahimi //  LDFF1SW_z_p_bz_d_64_unscaled
4426*f5c631daSSadaf Ebrahimi //  LDFF1SW_z_p_bz_d_x32_scaled
4427*f5c631daSSadaf Ebrahimi //  LDFF1SW_z_p_bz_d_x32_unscaled
ldff1sw(const ZRegister & zt,const PRegisterZ & pg,const Register & xn,const ZRegister & zm)4428*f5c631daSSadaf Ebrahimi void Assembler::ldff1sw(const ZRegister& zt,
4429*f5c631daSSadaf Ebrahimi                         const PRegisterZ& pg,
4430*f5c631daSSadaf Ebrahimi                         const Register& xn,
4431*f5c631daSSadaf Ebrahimi                         const ZRegister& zm) {
4432*f5c631daSSadaf Ebrahimi   // LDFF1SW { <Zt>.D }, <Pg>/Z, [<Xn|SP>, <Zm>.D, LSL #2]
4433*f5c631daSSadaf Ebrahimi   //  1100 0101 011. .... 101. .... .... ....
4434*f5c631daSSadaf Ebrahimi   //  msz<24:23> = 10 | Zm<20:16> | U<14> = 0 | ff<13> = 1 | Pg<12:10> | Rn<9:5>
4435*f5c631daSSadaf Ebrahimi   //  | Zt<4:0>
4436*f5c631daSSadaf Ebrahimi 
4437*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4438*f5c631daSSadaf Ebrahimi 
4439*f5c631daSSadaf Ebrahimi   Emit(LDFF1SW_z_p_bz_d_64_scaled | Rt(zt) | PgLow8(pg) | RnSP(xn) | Rm(zm));
4440*f5c631daSSadaf Ebrahimi }
4441*f5c631daSSadaf Ebrahimi 
ldff1sw(const ZRegister & zt,const PRegisterZ & pg,const ZRegister & zn,int imm5)4442*f5c631daSSadaf Ebrahimi void Assembler::ldff1sw(const ZRegister& zt,
4443*f5c631daSSadaf Ebrahimi                         const PRegisterZ& pg,
4444*f5c631daSSadaf Ebrahimi                         const ZRegister& zn,
4445*f5c631daSSadaf Ebrahimi                         int imm5) {
4446*f5c631daSSadaf Ebrahimi   // LDFF1SW { <Zt>.D }, <Pg>/Z, [<Zn>.D{, #<imm>}]
4447*f5c631daSSadaf Ebrahimi   //  1100 0101 001. .... 101. .... .... ....
4448*f5c631daSSadaf Ebrahimi   //  msz<24:23> = 10 | imm5<20:16> | U<14> = 0 | ff<13> = 1 | Pg<12:10> |
4449*f5c631daSSadaf Ebrahimi   //  Zn<9:5> | Zt<4:0>
4450*f5c631daSSadaf Ebrahimi 
4451*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4452*f5c631daSSadaf Ebrahimi 
4453*f5c631daSSadaf Ebrahimi   Emit(LDFF1SW_z_p_ai_d | Rt(zt) | PgLow8(pg) | Rn(zn) |
4454*f5c631daSSadaf Ebrahimi        ImmField<20, 16>(imm5));
4455*f5c631daSSadaf Ebrahimi }
4456*f5c631daSSadaf Ebrahimi 
4457*f5c631daSSadaf Ebrahimi // This prototype maps to 6 instruction encodings:
4458*f5c631daSSadaf Ebrahimi //  LDFF1W_z_p_bz_d_64_scaled
4459*f5c631daSSadaf Ebrahimi //  LDFF1W_z_p_bz_d_64_unscaled
4460*f5c631daSSadaf Ebrahimi //  LDFF1W_z_p_bz_d_x32_scaled
4461*f5c631daSSadaf Ebrahimi //  LDFF1W_z_p_bz_d_x32_unscaled
ldff1w(const ZRegister & zt,const PRegisterZ & pg,const Register & xn,const ZRegister & zm)4462*f5c631daSSadaf Ebrahimi void Assembler::ldff1w(const ZRegister& zt,
4463*f5c631daSSadaf Ebrahimi                        const PRegisterZ& pg,
4464*f5c631daSSadaf Ebrahimi                        const Register& xn,
4465*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
4466*f5c631daSSadaf Ebrahimi   // LDFF1W { <Zt>.D }, <Pg>/Z, [<Xn|SP>, <Zm>.D, LSL #2]
4467*f5c631daSSadaf Ebrahimi   //  1100 0101 011. .... 111. .... .... ....
4468*f5c631daSSadaf Ebrahimi   //  msz<24:23> = 10 | Zm<20:16> | U<14> = 1 | ff<13> = 1 | Pg<12:10> | Rn<9:5>
4469*f5c631daSSadaf Ebrahimi   //  | Zt<4:0>
4470*f5c631daSSadaf Ebrahimi 
4471*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4472*f5c631daSSadaf Ebrahimi 
4473*f5c631daSSadaf Ebrahimi   Emit(LDFF1W_z_p_bz_d_64_scaled | Rt(zt) | PgLow8(pg) | RnSP(xn) | Rm(zm));
4474*f5c631daSSadaf Ebrahimi }
4475*f5c631daSSadaf Ebrahimi 
4476*f5c631daSSadaf Ebrahimi // This prototype maps to 2 instruction encodings:
4477*f5c631daSSadaf Ebrahimi //  LDFF1W_z_p_ai_d
4478*f5c631daSSadaf Ebrahimi //  LDFF1W_z_p_ai_s
ldff1w(const ZRegister & zt,const PRegisterZ & pg,const ZRegister & zn,int imm5)4479*f5c631daSSadaf Ebrahimi void Assembler::ldff1w(const ZRegister& zt,
4480*f5c631daSSadaf Ebrahimi                        const PRegisterZ& pg,
4481*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
4482*f5c631daSSadaf Ebrahimi                        int imm5) {
4483*f5c631daSSadaf Ebrahimi   // LDFF1W { <Zt>.D }, <Pg>/Z, [<Zn>.D{, #<imm>}]
4484*f5c631daSSadaf Ebrahimi   //  1100 0101 001. .... 111. .... .... ....
4485*f5c631daSSadaf Ebrahimi   //  msz<24:23> = 10 | imm5<20:16> | U<14> = 1 | ff<13> = 1 | Pg<12:10> |
4486*f5c631daSSadaf Ebrahimi   //  Zn<9:5> | Zt<4:0>
4487*f5c631daSSadaf Ebrahimi 
4488*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4489*f5c631daSSadaf Ebrahimi 
4490*f5c631daSSadaf Ebrahimi   Emit(LDFF1W_z_p_ai_d | Rt(zt) | PgLow8(pg) | Rn(zn) | ImmField<20, 16>(imm5));
4491*f5c631daSSadaf Ebrahimi }
4492*f5c631daSSadaf Ebrahimi 
SVEGatherPrefetchVectorPlusImmediateHelper(PrefetchOperation prfop,const PRegister & pg,const SVEMemOperand & addr,int prefetch_size)4493*f5c631daSSadaf Ebrahimi void Assembler::SVEGatherPrefetchVectorPlusImmediateHelper(
4494*f5c631daSSadaf Ebrahimi     PrefetchOperation prfop,
4495*f5c631daSSadaf Ebrahimi     const PRegister& pg,
4496*f5c631daSSadaf Ebrahimi     const SVEMemOperand& addr,
4497*f5c631daSSadaf Ebrahimi     int prefetch_size) {
4498*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsVectorPlusImmediate());
4499*f5c631daSSadaf Ebrahimi   ZRegister zn = addr.GetVectorBase();
4500*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.IsLaneSizeS() || zn.IsLaneSizeD());
4501*f5c631daSSadaf Ebrahimi 
4502*f5c631daSSadaf Ebrahimi   Instr op = 0xffffffff;
4503*f5c631daSSadaf Ebrahimi   switch (prefetch_size) {
4504*f5c631daSSadaf Ebrahimi     case kBRegSize:
4505*f5c631daSSadaf Ebrahimi       op = zn.IsLaneSizeS() ? static_cast<Instr>(PRFB_i_p_ai_s)
4506*f5c631daSSadaf Ebrahimi                             : static_cast<Instr>(PRFB_i_p_ai_d);
4507*f5c631daSSadaf Ebrahimi       break;
4508*f5c631daSSadaf Ebrahimi     case kHRegSize:
4509*f5c631daSSadaf Ebrahimi       op = zn.IsLaneSizeS() ? static_cast<Instr>(PRFH_i_p_ai_s)
4510*f5c631daSSadaf Ebrahimi                             : static_cast<Instr>(PRFH_i_p_ai_d);
4511*f5c631daSSadaf Ebrahimi       break;
4512*f5c631daSSadaf Ebrahimi     case kSRegSize:
4513*f5c631daSSadaf Ebrahimi       op = zn.IsLaneSizeS() ? static_cast<Instr>(PRFW_i_p_ai_s)
4514*f5c631daSSadaf Ebrahimi                             : static_cast<Instr>(PRFW_i_p_ai_d);
4515*f5c631daSSadaf Ebrahimi       break;
4516*f5c631daSSadaf Ebrahimi     case kDRegSize:
4517*f5c631daSSadaf Ebrahimi       op = zn.IsLaneSizeS() ? static_cast<Instr>(PRFD_i_p_ai_s)
4518*f5c631daSSadaf Ebrahimi                             : static_cast<Instr>(PRFD_i_p_ai_d);
4519*f5c631daSSadaf Ebrahimi       break;
4520*f5c631daSSadaf Ebrahimi     default:
4521*f5c631daSSadaf Ebrahimi       VIXL_UNIMPLEMENTED();
4522*f5c631daSSadaf Ebrahimi       break;
4523*f5c631daSSadaf Ebrahimi   }
4524*f5c631daSSadaf Ebrahimi 
4525*f5c631daSSadaf Ebrahimi   int64_t imm5 = addr.GetImmediateOffset();
4526*f5c631daSSadaf Ebrahimi   Emit(op | SVEImmPrefetchOperation(prfop) | PgLow8(pg) | Rn(zn) |
4527*f5c631daSSadaf Ebrahimi        ImmUnsignedField<20, 16>(imm5));
4528*f5c631daSSadaf Ebrahimi }
4529*f5c631daSSadaf Ebrahimi 
SVEGatherPrefetchScalarPlusImmediateHelper(PrefetchOperation prfop,const PRegister & pg,const SVEMemOperand & addr,int prefetch_size)4530*f5c631daSSadaf Ebrahimi void Assembler::SVEGatherPrefetchScalarPlusImmediateHelper(
4531*f5c631daSSadaf Ebrahimi     PrefetchOperation prfop,
4532*f5c631daSSadaf Ebrahimi     const PRegister& pg,
4533*f5c631daSSadaf Ebrahimi     const SVEMemOperand& addr,
4534*f5c631daSSadaf Ebrahimi     int prefetch_size) {
4535*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsScalarPlusImmediate());
4536*f5c631daSSadaf Ebrahimi   int64_t imm6 = addr.GetImmediateOffset();
4537*f5c631daSSadaf Ebrahimi 
4538*f5c631daSSadaf Ebrahimi   Instr op = 0xffffffff;
4539*f5c631daSSadaf Ebrahimi   switch (prefetch_size) {
4540*f5c631daSSadaf Ebrahimi     case kBRegSize:
4541*f5c631daSSadaf Ebrahimi       op = PRFB_i_p_bi_s;
4542*f5c631daSSadaf Ebrahimi       break;
4543*f5c631daSSadaf Ebrahimi     case kHRegSize:
4544*f5c631daSSadaf Ebrahimi       op = PRFH_i_p_bi_s;
4545*f5c631daSSadaf Ebrahimi       break;
4546*f5c631daSSadaf Ebrahimi     case kSRegSize:
4547*f5c631daSSadaf Ebrahimi       op = PRFW_i_p_bi_s;
4548*f5c631daSSadaf Ebrahimi       break;
4549*f5c631daSSadaf Ebrahimi     case kDRegSize:
4550*f5c631daSSadaf Ebrahimi       op = PRFD_i_p_bi_s;
4551*f5c631daSSadaf Ebrahimi       break;
4552*f5c631daSSadaf Ebrahimi     default:
4553*f5c631daSSadaf Ebrahimi       VIXL_UNIMPLEMENTED();
4554*f5c631daSSadaf Ebrahimi       break;
4555*f5c631daSSadaf Ebrahimi   }
4556*f5c631daSSadaf Ebrahimi 
4557*f5c631daSSadaf Ebrahimi   Emit(op | SVEImmPrefetchOperation(prfop) | PgLow8(pg) |
4558*f5c631daSSadaf Ebrahimi        RnSP(addr.GetScalarBase()) | ImmField<21, 16>(imm6));
4559*f5c631daSSadaf Ebrahimi }
4560*f5c631daSSadaf Ebrahimi 
SVEContiguousPrefetchScalarPlusScalarHelper(PrefetchOperation prfop,const PRegister & pg,const SVEMemOperand & addr,int prefetch_size)4561*f5c631daSSadaf Ebrahimi void Assembler::SVEContiguousPrefetchScalarPlusScalarHelper(
4562*f5c631daSSadaf Ebrahimi     PrefetchOperation prfop,
4563*f5c631daSSadaf Ebrahimi     const PRegister& pg,
4564*f5c631daSSadaf Ebrahimi     const SVEMemOperand& addr,
4565*f5c631daSSadaf Ebrahimi     int prefetch_size) {
4566*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsScalarPlusScalar());
4567*f5c631daSSadaf Ebrahimi   Instr op = 0xffffffff;
4568*f5c631daSSadaf Ebrahimi 
4569*f5c631daSSadaf Ebrahimi   switch (prefetch_size) {
4570*f5c631daSSadaf Ebrahimi     case kBRegSize:
4571*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(addr.GetOffsetModifier() == NO_SVE_OFFSET_MODIFIER);
4572*f5c631daSSadaf Ebrahimi       op = PRFB_i_p_br_s;
4573*f5c631daSSadaf Ebrahimi       break;
4574*f5c631daSSadaf Ebrahimi     case kHRegSize:
4575*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(addr.GetOffsetModifier() == SVE_LSL);
4576*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(addr.GetShiftAmount() == kHRegSizeInBytesLog2);
4577*f5c631daSSadaf Ebrahimi       op = PRFH_i_p_br_s;
4578*f5c631daSSadaf Ebrahimi       break;
4579*f5c631daSSadaf Ebrahimi     case kSRegSize:
4580*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(addr.GetOffsetModifier() == SVE_LSL);
4581*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(addr.GetShiftAmount() == kSRegSizeInBytesLog2);
4582*f5c631daSSadaf Ebrahimi       op = PRFW_i_p_br_s;
4583*f5c631daSSadaf Ebrahimi       break;
4584*f5c631daSSadaf Ebrahimi     case kDRegSize:
4585*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(addr.GetOffsetModifier() == SVE_LSL);
4586*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(addr.GetShiftAmount() == kDRegSizeInBytesLog2);
4587*f5c631daSSadaf Ebrahimi       op = PRFD_i_p_br_s;
4588*f5c631daSSadaf Ebrahimi       break;
4589*f5c631daSSadaf Ebrahimi     default:
4590*f5c631daSSadaf Ebrahimi       VIXL_UNIMPLEMENTED();
4591*f5c631daSSadaf Ebrahimi       break;
4592*f5c631daSSadaf Ebrahimi   }
4593*f5c631daSSadaf Ebrahimi 
4594*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!addr.GetScalarOffset().IsZero());
4595*f5c631daSSadaf Ebrahimi   Emit(op | SVEImmPrefetchOperation(prfop) | PgLow8(pg) |
4596*f5c631daSSadaf Ebrahimi        RnSP(addr.GetScalarBase()) | Rm(addr.GetScalarOffset()));
4597*f5c631daSSadaf Ebrahimi }
4598*f5c631daSSadaf Ebrahimi 
SVEContiguousPrefetchScalarPlusVectorHelper(PrefetchOperation prfop,const PRegister & pg,const SVEMemOperand & addr,int prefetch_size)4599*f5c631daSSadaf Ebrahimi void Assembler::SVEContiguousPrefetchScalarPlusVectorHelper(
4600*f5c631daSSadaf Ebrahimi     PrefetchOperation prfop,
4601*f5c631daSSadaf Ebrahimi     const PRegister& pg,
4602*f5c631daSSadaf Ebrahimi     const SVEMemOperand& addr,
4603*f5c631daSSadaf Ebrahimi     int prefetch_size) {
4604*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsScalarPlusVector());
4605*f5c631daSSadaf Ebrahimi   ZRegister zm = addr.GetVectorOffset();
4606*f5c631daSSadaf Ebrahimi   SVEOffsetModifier mod = addr.GetOffsetModifier();
4607*f5c631daSSadaf Ebrahimi 
4608*f5c631daSSadaf Ebrahimi   // All prefetch scalar-plus-vector addressing modes use a shift corresponding
4609*f5c631daSSadaf Ebrahimi   // to the element size.
4610*f5c631daSSadaf Ebrahimi   switch (prefetch_size) {
4611*f5c631daSSadaf Ebrahimi     case kBRegSize:
4612*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(addr.GetShiftAmount() == kBRegSizeInBytesLog2);
4613*f5c631daSSadaf Ebrahimi       break;
4614*f5c631daSSadaf Ebrahimi     case kHRegSize:
4615*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(addr.GetShiftAmount() == kHRegSizeInBytesLog2);
4616*f5c631daSSadaf Ebrahimi       break;
4617*f5c631daSSadaf Ebrahimi     case kSRegSize:
4618*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(addr.GetShiftAmount() == kSRegSizeInBytesLog2);
4619*f5c631daSSadaf Ebrahimi       break;
4620*f5c631daSSadaf Ebrahimi     case kDRegSize:
4621*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(addr.GetShiftAmount() == kDRegSizeInBytesLog2);
4622*f5c631daSSadaf Ebrahimi       break;
4623*f5c631daSSadaf Ebrahimi     default:
4624*f5c631daSSadaf Ebrahimi       VIXL_UNIMPLEMENTED();
4625*f5c631daSSadaf Ebrahimi       break;
4626*f5c631daSSadaf Ebrahimi   }
4627*f5c631daSSadaf Ebrahimi 
4628*f5c631daSSadaf Ebrahimi   Instr sx = 0;
4629*f5c631daSSadaf Ebrahimi   Instr op = 0xffffffff;
4630*f5c631daSSadaf Ebrahimi   if ((mod == NO_SVE_OFFSET_MODIFIER) || (mod == SVE_LSL)) {
4631*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zm.IsLaneSizeD());
4632*f5c631daSSadaf Ebrahimi 
4633*f5c631daSSadaf Ebrahimi     switch (prefetch_size) {
4634*f5c631daSSadaf Ebrahimi       case kBRegSize:
4635*f5c631daSSadaf Ebrahimi         VIXL_ASSERT(mod == NO_SVE_OFFSET_MODIFIER);
4636*f5c631daSSadaf Ebrahimi         op = PRFB_i_p_bz_d_64_scaled;
4637*f5c631daSSadaf Ebrahimi         break;
4638*f5c631daSSadaf Ebrahimi       case kHRegSize:
4639*f5c631daSSadaf Ebrahimi         VIXL_ASSERT(mod == SVE_LSL);
4640*f5c631daSSadaf Ebrahimi         op = PRFH_i_p_bz_d_64_scaled;
4641*f5c631daSSadaf Ebrahimi         break;
4642*f5c631daSSadaf Ebrahimi       case kSRegSize:
4643*f5c631daSSadaf Ebrahimi         VIXL_ASSERT(mod == SVE_LSL);
4644*f5c631daSSadaf Ebrahimi         op = PRFW_i_p_bz_d_64_scaled;
4645*f5c631daSSadaf Ebrahimi         break;
4646*f5c631daSSadaf Ebrahimi       case kDRegSize:
4647*f5c631daSSadaf Ebrahimi         VIXL_ASSERT(mod == SVE_LSL);
4648*f5c631daSSadaf Ebrahimi         op = PRFD_i_p_bz_d_64_scaled;
4649*f5c631daSSadaf Ebrahimi         break;
4650*f5c631daSSadaf Ebrahimi       default:
4651*f5c631daSSadaf Ebrahimi         VIXL_UNIMPLEMENTED();
4652*f5c631daSSadaf Ebrahimi         break;
4653*f5c631daSSadaf Ebrahimi     }
4654*f5c631daSSadaf Ebrahimi   } else {
4655*f5c631daSSadaf Ebrahimi     VIXL_ASSERT((mod == SVE_SXTW) || (mod == SVE_UXTW));
4656*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zm.IsLaneSizeS() || zm.IsLaneSizeD());
4657*f5c631daSSadaf Ebrahimi 
4658*f5c631daSSadaf Ebrahimi     switch (prefetch_size) {
4659*f5c631daSSadaf Ebrahimi       case kBRegSize:
4660*f5c631daSSadaf Ebrahimi         op = zm.IsLaneSizeS() ? static_cast<Instr>(PRFB_i_p_bz_s_x32_scaled)
4661*f5c631daSSadaf Ebrahimi                               : static_cast<Instr>(PRFB_i_p_bz_d_x32_scaled);
4662*f5c631daSSadaf Ebrahimi         break;
4663*f5c631daSSadaf Ebrahimi       case kHRegSize:
4664*f5c631daSSadaf Ebrahimi         op = zm.IsLaneSizeS() ? static_cast<Instr>(PRFH_i_p_bz_s_x32_scaled)
4665*f5c631daSSadaf Ebrahimi                               : static_cast<Instr>(PRFH_i_p_bz_d_x32_scaled);
4666*f5c631daSSadaf Ebrahimi         break;
4667*f5c631daSSadaf Ebrahimi       case kSRegSize:
4668*f5c631daSSadaf Ebrahimi         op = zm.IsLaneSizeS() ? static_cast<Instr>(PRFW_i_p_bz_s_x32_scaled)
4669*f5c631daSSadaf Ebrahimi                               : static_cast<Instr>(PRFW_i_p_bz_d_x32_scaled);
4670*f5c631daSSadaf Ebrahimi         break;
4671*f5c631daSSadaf Ebrahimi       case kDRegSize:
4672*f5c631daSSadaf Ebrahimi         op = zm.IsLaneSizeS() ? static_cast<Instr>(PRFD_i_p_bz_s_x32_scaled)
4673*f5c631daSSadaf Ebrahimi                               : static_cast<Instr>(PRFD_i_p_bz_d_x32_scaled);
4674*f5c631daSSadaf Ebrahimi         break;
4675*f5c631daSSadaf Ebrahimi       default:
4676*f5c631daSSadaf Ebrahimi         VIXL_UNIMPLEMENTED();
4677*f5c631daSSadaf Ebrahimi         break;
4678*f5c631daSSadaf Ebrahimi     }
4679*f5c631daSSadaf Ebrahimi 
4680*f5c631daSSadaf Ebrahimi     if (mod == SVE_SXTW) {
4681*f5c631daSSadaf Ebrahimi       sx = 1 << 22;
4682*f5c631daSSadaf Ebrahimi     }
4683*f5c631daSSadaf Ebrahimi   }
4684*f5c631daSSadaf Ebrahimi 
4685*f5c631daSSadaf Ebrahimi   Emit(op | SVEImmPrefetchOperation(prfop) | PgLow8(pg) | sx |
4686*f5c631daSSadaf Ebrahimi        RnSP(addr.GetScalarBase()) | Rm(zm));
4687*f5c631daSSadaf Ebrahimi }
4688*f5c631daSSadaf Ebrahimi 
SVEPrefetchHelper(PrefetchOperation prfop,const PRegister & pg,const SVEMemOperand & addr,int prefetch_size)4689*f5c631daSSadaf Ebrahimi void Assembler::SVEPrefetchHelper(PrefetchOperation prfop,
4690*f5c631daSSadaf Ebrahimi                                   const PRegister& pg,
4691*f5c631daSSadaf Ebrahimi                                   const SVEMemOperand& addr,
4692*f5c631daSSadaf Ebrahimi                                   int prefetch_size) {
4693*f5c631daSSadaf Ebrahimi   if (addr.IsVectorPlusImmediate()) {
4694*f5c631daSSadaf Ebrahimi     // For example:
4695*f5c631daSSadaf Ebrahimi     //   [z0.s, #0]
4696*f5c631daSSadaf Ebrahimi     SVEGatherPrefetchVectorPlusImmediateHelper(prfop, pg, addr, prefetch_size);
4697*f5c631daSSadaf Ebrahimi 
4698*f5c631daSSadaf Ebrahimi   } else if (addr.IsScalarPlusImmediate()) {
4699*f5c631daSSadaf Ebrahimi     // For example:
4700*f5c631daSSadaf Ebrahimi     //   [x0, #42, mul vl]
4701*f5c631daSSadaf Ebrahimi     SVEGatherPrefetchScalarPlusImmediateHelper(prfop, pg, addr, prefetch_size);
4702*f5c631daSSadaf Ebrahimi 
4703*f5c631daSSadaf Ebrahimi   } else if (addr.IsScalarPlusVector()) {
4704*f5c631daSSadaf Ebrahimi     // For example:
4705*f5c631daSSadaf Ebrahimi     //   [x0, z0.s, sxtw]
4706*f5c631daSSadaf Ebrahimi     SVEContiguousPrefetchScalarPlusVectorHelper(prfop, pg, addr, prefetch_size);
4707*f5c631daSSadaf Ebrahimi 
4708*f5c631daSSadaf Ebrahimi   } else if (addr.IsScalarPlusScalar()) {
4709*f5c631daSSadaf Ebrahimi     // For example:
4710*f5c631daSSadaf Ebrahimi     //   [x0, x1]
4711*f5c631daSSadaf Ebrahimi     SVEContiguousPrefetchScalarPlusScalarHelper(prfop, pg, addr, prefetch_size);
4712*f5c631daSSadaf Ebrahimi 
4713*f5c631daSSadaf Ebrahimi   } else {
4714*f5c631daSSadaf Ebrahimi     VIXL_UNIMPLEMENTED();
4715*f5c631daSSadaf Ebrahimi   }
4716*f5c631daSSadaf Ebrahimi }
4717*f5c631daSSadaf Ebrahimi 
prfb(PrefetchOperation prfop,const PRegister & pg,const SVEMemOperand & addr)4718*f5c631daSSadaf Ebrahimi void Assembler::prfb(PrefetchOperation prfop,
4719*f5c631daSSadaf Ebrahimi                      const PRegister& pg,
4720*f5c631daSSadaf Ebrahimi                      const SVEMemOperand& addr) {
4721*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4722*f5c631daSSadaf Ebrahimi   SVEPrefetchHelper(prfop, pg, addr, kBRegSize);
4723*f5c631daSSadaf Ebrahimi }
4724*f5c631daSSadaf Ebrahimi 
prfd(PrefetchOperation prfop,const PRegister & pg,const SVEMemOperand & addr)4725*f5c631daSSadaf Ebrahimi void Assembler::prfd(PrefetchOperation prfop,
4726*f5c631daSSadaf Ebrahimi                      const PRegister& pg,
4727*f5c631daSSadaf Ebrahimi                      const SVEMemOperand& addr) {
4728*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4729*f5c631daSSadaf Ebrahimi   SVEPrefetchHelper(prfop, pg, addr, kDRegSize);
4730*f5c631daSSadaf Ebrahimi }
4731*f5c631daSSadaf Ebrahimi 
prfh(PrefetchOperation prfop,const PRegister & pg,const SVEMemOperand & addr)4732*f5c631daSSadaf Ebrahimi void Assembler::prfh(PrefetchOperation prfop,
4733*f5c631daSSadaf Ebrahimi                      const PRegister& pg,
4734*f5c631daSSadaf Ebrahimi                      const SVEMemOperand& addr) {
4735*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4736*f5c631daSSadaf Ebrahimi   SVEPrefetchHelper(prfop, pg, addr, kHRegSize);
4737*f5c631daSSadaf Ebrahimi }
4738*f5c631daSSadaf Ebrahimi 
prfw(PrefetchOperation prfop,const PRegister & pg,const SVEMemOperand & addr)4739*f5c631daSSadaf Ebrahimi void Assembler::prfw(PrefetchOperation prfop,
4740*f5c631daSSadaf Ebrahimi                      const PRegister& pg,
4741*f5c631daSSadaf Ebrahimi                      const SVEMemOperand& addr) {
4742*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4743*f5c631daSSadaf Ebrahimi   SVEPrefetchHelper(prfop, pg, addr, kSRegSize);
4744*f5c631daSSadaf Ebrahimi }
4745*f5c631daSSadaf Ebrahimi 
SVELd1St1ScaImmHelper(const ZRegister & zt,const PRegister & pg,const SVEMemOperand & addr,Instr regoffset_op,Instr immoffset_op,int imm_divisor)4746*f5c631daSSadaf Ebrahimi void Assembler::SVELd1St1ScaImmHelper(const ZRegister& zt,
4747*f5c631daSSadaf Ebrahimi                                       const PRegister& pg,
4748*f5c631daSSadaf Ebrahimi                                       const SVEMemOperand& addr,
4749*f5c631daSSadaf Ebrahimi                                       Instr regoffset_op,
4750*f5c631daSSadaf Ebrahimi                                       Instr immoffset_op,
4751*f5c631daSSadaf Ebrahimi                                       int imm_divisor) {
4752*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4753*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsScalarPlusScalar() || addr.IsScalarPlusImmediate());
4754*f5c631daSSadaf Ebrahimi 
4755*f5c631daSSadaf Ebrahimi   Instr op;
4756*f5c631daSSadaf Ebrahimi   if (addr.IsScalarPlusScalar()) {
4757*f5c631daSSadaf Ebrahimi     op = regoffset_op | Rm(addr.GetScalarOffset());
4758*f5c631daSSadaf Ebrahimi   } else {
4759*f5c631daSSadaf Ebrahimi     int64_t imm = addr.GetImmediateOffset();
4760*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(((imm % imm_divisor) == 0) && IsInt4(imm / imm_divisor));
4761*f5c631daSSadaf Ebrahimi     op = immoffset_op | ImmField<19, 16>(imm / imm_divisor);
4762*f5c631daSSadaf Ebrahimi   }
4763*f5c631daSSadaf Ebrahimi   Emit(op | Rt(zt) | PgLow8(pg) | RnSP(addr.GetScalarBase()));
4764*f5c631daSSadaf Ebrahimi }
4765*f5c631daSSadaf Ebrahimi 
SVELd1VecScaHelper(const ZRegister & zt,const PRegister & pg,const SVEMemOperand & addr,uint32_t msize_bytes_log2,bool is_signed)4766*f5c631daSSadaf Ebrahimi void Assembler::SVELd1VecScaHelper(const ZRegister& zt,
4767*f5c631daSSadaf Ebrahimi                                    const PRegister& pg,
4768*f5c631daSSadaf Ebrahimi                                    const SVEMemOperand& addr,
4769*f5c631daSSadaf Ebrahimi                                    uint32_t msize_bytes_log2,
4770*f5c631daSSadaf Ebrahimi                                    bool is_signed) {
4771*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
4772*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsVectorPlusScalar());
4773*f5c631daSSadaf Ebrahimi   ZRegister zn = addr.GetVectorBase();
4774*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.IsLaneSizeS() || zn.IsLaneSizeD());
4775*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zt));
4776*f5c631daSSadaf Ebrahimi 
4777*f5c631daSSadaf Ebrahimi   uint32_t esize = zn.GetLaneSizeInBytesLog2();
4778*f5c631daSSadaf Ebrahimi   uint32_t b14_13 = 0;
4779*f5c631daSSadaf Ebrahimi   if (!is_signed) b14_13 = zn.IsLaneSizeS() ? 0x1 : 0x2;
4780*f5c631daSSadaf Ebrahimi 
4781*f5c631daSSadaf Ebrahimi   Instr op = 0x04008000;  // LDNT1 with vector plus scalar addressing mode.
4782*f5c631daSSadaf Ebrahimi   op |= (esize << 30) | (msize_bytes_log2 << 23) | (b14_13 << 13);
4783*f5c631daSSadaf Ebrahimi   Emit(op | Rt(zt) | PgLow8(pg) |
4784*f5c631daSSadaf Ebrahimi        SVEMemOperandHelper(msize_bytes_log2, 1, addr, true));
4785*f5c631daSSadaf Ebrahimi }
4786*f5c631daSSadaf Ebrahimi 
SVESt1VecScaHelper(const ZRegister & zt,const PRegister & pg,const SVEMemOperand & addr,uint32_t msize_bytes_log2)4787*f5c631daSSadaf Ebrahimi void Assembler::SVESt1VecScaHelper(const ZRegister& zt,
4788*f5c631daSSadaf Ebrahimi                                    const PRegister& pg,
4789*f5c631daSSadaf Ebrahimi                                    const SVEMemOperand& addr,
4790*f5c631daSSadaf Ebrahimi                                    uint32_t msize_bytes_log2) {
4791*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
4792*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsVectorPlusScalar());
4793*f5c631daSSadaf Ebrahimi   ZRegister zn = addr.GetVectorBase();
4794*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.IsLaneSizeS() || zn.IsLaneSizeD());
4795*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zt));
4796*f5c631daSSadaf Ebrahimi 
4797*f5c631daSSadaf Ebrahimi   uint32_t bit22 = zn.IsLaneSizeS() ? (1 << 22) : 0;
4798*f5c631daSSadaf Ebrahimi   Instr op = 0xe4002000;  // STNT1 with vector plus scalar addressing mode.
4799*f5c631daSSadaf Ebrahimi   op |= bit22 | (msize_bytes_log2 << 23);
4800*f5c631daSSadaf Ebrahimi   Emit(op | Rt(zt) | PgLow8(pg) |
4801*f5c631daSSadaf Ebrahimi        SVEMemOperandHelper(msize_bytes_log2, 1, addr, true));
4802*f5c631daSSadaf Ebrahimi }
4803*f5c631daSSadaf Ebrahimi 
4804*f5c631daSSadaf Ebrahimi #define VIXL_SVE_LD1R_LIST(V)                                  \
4805*f5c631daSSadaf Ebrahimi   V(qb, 0, B, LD1RQB_z_p_br_contiguous, LD1RQB_z_p_bi_u8, 16)  \
4806*f5c631daSSadaf Ebrahimi   V(qh, 1, H, LD1RQH_z_p_br_contiguous, LD1RQH_z_p_bi_u16, 16) \
4807*f5c631daSSadaf Ebrahimi   V(qw, 2, S, LD1RQW_z_p_br_contiguous, LD1RQW_z_p_bi_u32, 16) \
4808*f5c631daSSadaf Ebrahimi   V(qd, 3, D, LD1RQD_z_p_br_contiguous, LD1RQD_z_p_bi_u64, 16) \
4809*f5c631daSSadaf Ebrahimi   V(ob, 0, B, 0xa4200000, 0xa4202000, 32)                      \
4810*f5c631daSSadaf Ebrahimi   V(oh, 1, H, 0xa4a00000, 0xa4a02000, 32)                      \
4811*f5c631daSSadaf Ebrahimi   V(ow, 2, S, 0xa5200000, 0xa5202000, 32)                      \
4812*f5c631daSSadaf Ebrahimi   V(od, 3, D, 0xa5a00000, 0xa5a02000, 32)
4813*f5c631daSSadaf Ebrahimi 
4814*f5c631daSSadaf Ebrahimi #define VIXL_DEFINE_ASM_FUNC(FN, SH, SZ, SCA, IMM, BYTES)                    \
4815*f5c631daSSadaf Ebrahimi   void Assembler::ld1r##FN(const ZRegister& zt,                              \
4816*f5c631daSSadaf Ebrahimi                            const PRegisterZ& pg,                             \
4817*f5c631daSSadaf Ebrahimi                            const SVEMemOperand& addr) {                      \
4818*f5c631daSSadaf Ebrahimi     VIXL_ASSERT((BYTES == 16) ||                                             \
4819*f5c631daSSadaf Ebrahimi                 ((BYTES == 32) && (CPUHas(CPUFeatures::kSVEF64MM))));        \
4820*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(addr.IsScalarPlusImmediate() || addr.IsEquivalentToLSL(SH)); \
4821*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zt.IsLaneSize##SZ());                                        \
4822*f5c631daSSadaf Ebrahimi     SVELd1St1ScaImmHelper(zt, pg, addr, SCA, IMM, BYTES);                    \
4823*f5c631daSSadaf Ebrahimi   }
4824*f5c631daSSadaf Ebrahimi VIXL_SVE_LD1R_LIST(VIXL_DEFINE_ASM_FUNC)
4825*f5c631daSSadaf Ebrahimi #undef VIXL_DEFINE_ASM_FUNC
4826*f5c631daSSadaf Ebrahimi #undef VIXL_SVE_LD1R_LIST
4827*f5c631daSSadaf Ebrahimi 
4828*f5c631daSSadaf Ebrahimi #define VIXL_DEFINE_LDFF1(MSZ, LANE_SIZE)                                  \
4829*f5c631daSSadaf Ebrahimi   void Assembler::ldff1##MSZ(const ZRegister& zt,                          \
4830*f5c631daSSadaf Ebrahimi                              const PRegisterZ& pg,                         \
4831*f5c631daSSadaf Ebrahimi                              const SVEMemOperand& addr) {                  \
4832*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));                                \
4833*f5c631daSSadaf Ebrahimi     SVELdff1Helper(k##LANE_SIZE##RegSizeInBytesLog2, zt, pg, addr, false); \
4834*f5c631daSSadaf Ebrahimi   }
VIXL_SVE_LOAD_STORE_VARIANT_LIST(VIXL_DEFINE_LDFF1)4835*f5c631daSSadaf Ebrahimi VIXL_SVE_LOAD_STORE_VARIANT_LIST(VIXL_DEFINE_LDFF1)
4836*f5c631daSSadaf Ebrahimi 
4837*f5c631daSSadaf Ebrahimi #define VIXL_DEFINE_LDFF1S(MSZ, LANE_SIZE)                                \
4838*f5c631daSSadaf Ebrahimi   void Assembler::ldff1s##MSZ(const ZRegister& zt,                        \
4839*f5c631daSSadaf Ebrahimi                               const PRegisterZ& pg,                       \
4840*f5c631daSSadaf Ebrahimi                               const SVEMemOperand& addr) {                \
4841*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));                               \
4842*f5c631daSSadaf Ebrahimi     SVELdff1Helper(k##LANE_SIZE##RegSizeInBytesLog2, zt, pg, addr, true); \
4843*f5c631daSSadaf Ebrahimi   }
4844*f5c631daSSadaf Ebrahimi VIXL_SVE_LOAD_STORE_SIGNED_VARIANT_LIST(VIXL_DEFINE_LDFF1S)
4845*f5c631daSSadaf Ebrahimi 
4846*f5c631daSSadaf Ebrahimi void Assembler::ldnf1b(const ZRegister& zt,
4847*f5c631daSSadaf Ebrahimi                        const PRegisterZ& pg,
4848*f5c631daSSadaf Ebrahimi                        const SVEMemOperand& addr) {
4849*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4850*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsPlainRegister() ||
4851*f5c631daSSadaf Ebrahimi               (addr.IsScalarPlusImmediate() &&
4852*f5c631daSSadaf Ebrahimi                (addr.GetOffsetModifier() == SVE_MUL_VL)));
4853*f5c631daSSadaf Ebrahimi 
4854*f5c631daSSadaf Ebrahimi   SVELdSt1Helper(0,
4855*f5c631daSSadaf Ebrahimi                  zt,
4856*f5c631daSSadaf Ebrahimi                  pg,
4857*f5c631daSSadaf Ebrahimi                  addr,
4858*f5c631daSSadaf Ebrahimi                  /* is_signed = */ false,
4859*f5c631daSSadaf Ebrahimi                  SVEContiguousNonFaultLoad_ScalarPlusImmFixed);
4860*f5c631daSSadaf Ebrahimi }
4861*f5c631daSSadaf Ebrahimi 
ldnf1d(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)4862*f5c631daSSadaf Ebrahimi void Assembler::ldnf1d(const ZRegister& zt,
4863*f5c631daSSadaf Ebrahimi                        const PRegisterZ& pg,
4864*f5c631daSSadaf Ebrahimi                        const SVEMemOperand& addr) {
4865*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4866*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsPlainRegister() ||
4867*f5c631daSSadaf Ebrahimi               (addr.IsScalarPlusImmediate() &&
4868*f5c631daSSadaf Ebrahimi                (addr.GetOffsetModifier() == SVE_MUL_VL)));
4869*f5c631daSSadaf Ebrahimi 
4870*f5c631daSSadaf Ebrahimi   SVELdSt1Helper(3,
4871*f5c631daSSadaf Ebrahimi                  zt,
4872*f5c631daSSadaf Ebrahimi                  pg,
4873*f5c631daSSadaf Ebrahimi                  addr,
4874*f5c631daSSadaf Ebrahimi                  /* is_signed = */ false,
4875*f5c631daSSadaf Ebrahimi                  SVEContiguousNonFaultLoad_ScalarPlusImmFixed);
4876*f5c631daSSadaf Ebrahimi }
4877*f5c631daSSadaf Ebrahimi 
ldnf1h(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)4878*f5c631daSSadaf Ebrahimi void Assembler::ldnf1h(const ZRegister& zt,
4879*f5c631daSSadaf Ebrahimi                        const PRegisterZ& pg,
4880*f5c631daSSadaf Ebrahimi                        const SVEMemOperand& addr) {
4881*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4882*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsPlainRegister() ||
4883*f5c631daSSadaf Ebrahimi               (addr.IsScalarPlusImmediate() &&
4884*f5c631daSSadaf Ebrahimi                (addr.GetOffsetModifier() == SVE_MUL_VL)));
4885*f5c631daSSadaf Ebrahimi 
4886*f5c631daSSadaf Ebrahimi   SVELdSt1Helper(1,
4887*f5c631daSSadaf Ebrahimi                  zt,
4888*f5c631daSSadaf Ebrahimi                  pg,
4889*f5c631daSSadaf Ebrahimi                  addr,
4890*f5c631daSSadaf Ebrahimi                  /* is_signed = */ false,
4891*f5c631daSSadaf Ebrahimi                  SVEContiguousNonFaultLoad_ScalarPlusImmFixed);
4892*f5c631daSSadaf Ebrahimi }
4893*f5c631daSSadaf Ebrahimi 
ldnf1sb(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)4894*f5c631daSSadaf Ebrahimi void Assembler::ldnf1sb(const ZRegister& zt,
4895*f5c631daSSadaf Ebrahimi                         const PRegisterZ& pg,
4896*f5c631daSSadaf Ebrahimi                         const SVEMemOperand& addr) {
4897*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4898*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsPlainRegister() ||
4899*f5c631daSSadaf Ebrahimi               (addr.IsScalarPlusImmediate() &&
4900*f5c631daSSadaf Ebrahimi                (addr.GetOffsetModifier() == SVE_MUL_VL)));
4901*f5c631daSSadaf Ebrahimi 
4902*f5c631daSSadaf Ebrahimi   SVELdSt1Helper(0,
4903*f5c631daSSadaf Ebrahimi                  zt,
4904*f5c631daSSadaf Ebrahimi                  pg,
4905*f5c631daSSadaf Ebrahimi                  addr,
4906*f5c631daSSadaf Ebrahimi                  /* is_signed = */ true,
4907*f5c631daSSadaf Ebrahimi                  SVEContiguousNonFaultLoad_ScalarPlusImmFixed);
4908*f5c631daSSadaf Ebrahimi }
4909*f5c631daSSadaf Ebrahimi 
ldnf1sh(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)4910*f5c631daSSadaf Ebrahimi void Assembler::ldnf1sh(const ZRegister& zt,
4911*f5c631daSSadaf Ebrahimi                         const PRegisterZ& pg,
4912*f5c631daSSadaf Ebrahimi                         const SVEMemOperand& addr) {
4913*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4914*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsPlainRegister() ||
4915*f5c631daSSadaf Ebrahimi               (addr.IsScalarPlusImmediate() &&
4916*f5c631daSSadaf Ebrahimi                (addr.GetOffsetModifier() == SVE_MUL_VL)));
4917*f5c631daSSadaf Ebrahimi 
4918*f5c631daSSadaf Ebrahimi   SVELdSt1Helper(1,
4919*f5c631daSSadaf Ebrahimi                  zt,
4920*f5c631daSSadaf Ebrahimi                  pg,
4921*f5c631daSSadaf Ebrahimi                  addr,
4922*f5c631daSSadaf Ebrahimi                  /* is_signed = */ true,
4923*f5c631daSSadaf Ebrahimi                  SVEContiguousNonFaultLoad_ScalarPlusImmFixed);
4924*f5c631daSSadaf Ebrahimi }
4925*f5c631daSSadaf Ebrahimi 
ldnf1sw(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)4926*f5c631daSSadaf Ebrahimi void Assembler::ldnf1sw(const ZRegister& zt,
4927*f5c631daSSadaf Ebrahimi                         const PRegisterZ& pg,
4928*f5c631daSSadaf Ebrahimi                         const SVEMemOperand& addr) {
4929*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4930*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsPlainRegister() ||
4931*f5c631daSSadaf Ebrahimi               (addr.IsScalarPlusImmediate() &&
4932*f5c631daSSadaf Ebrahimi                (addr.GetOffsetModifier() == SVE_MUL_VL)));
4933*f5c631daSSadaf Ebrahimi 
4934*f5c631daSSadaf Ebrahimi   SVELdSt1Helper(2,
4935*f5c631daSSadaf Ebrahimi                  zt,
4936*f5c631daSSadaf Ebrahimi                  pg,
4937*f5c631daSSadaf Ebrahimi                  addr,
4938*f5c631daSSadaf Ebrahimi                  /* is_signed = */ true,
4939*f5c631daSSadaf Ebrahimi                  SVEContiguousNonFaultLoad_ScalarPlusImmFixed);
4940*f5c631daSSadaf Ebrahimi }
4941*f5c631daSSadaf Ebrahimi 
ldnf1w(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)4942*f5c631daSSadaf Ebrahimi void Assembler::ldnf1w(const ZRegister& zt,
4943*f5c631daSSadaf Ebrahimi                        const PRegisterZ& pg,
4944*f5c631daSSadaf Ebrahimi                        const SVEMemOperand& addr) {
4945*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
4946*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsPlainRegister() ||
4947*f5c631daSSadaf Ebrahimi               (addr.IsScalarPlusImmediate() &&
4948*f5c631daSSadaf Ebrahimi                (addr.GetOffsetModifier() == SVE_MUL_VL)));
4949*f5c631daSSadaf Ebrahimi 
4950*f5c631daSSadaf Ebrahimi   SVELdSt1Helper(2,
4951*f5c631daSSadaf Ebrahimi                  zt,
4952*f5c631daSSadaf Ebrahimi                  pg,
4953*f5c631daSSadaf Ebrahimi                  addr,
4954*f5c631daSSadaf Ebrahimi                  /* is_signed = */ false,
4955*f5c631daSSadaf Ebrahimi                  SVEContiguousNonFaultLoad_ScalarPlusImmFixed);
4956*f5c631daSSadaf Ebrahimi }
4957*f5c631daSSadaf Ebrahimi 
ldnt1b(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)4958*f5c631daSSadaf Ebrahimi void Assembler::ldnt1b(const ZRegister& zt,
4959*f5c631daSSadaf Ebrahimi                        const PRegisterZ& pg,
4960*f5c631daSSadaf Ebrahimi                        const SVEMemOperand& addr) {
4961*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsPlainScalar() ||
4962*f5c631daSSadaf Ebrahimi               (addr.IsScalarPlusImmediate() && addr.IsMulVl()) ||
4963*f5c631daSSadaf Ebrahimi               (addr.IsScalarPlusScalar() && addr.IsEquivalentToLSL(0)) ||
4964*f5c631daSSadaf Ebrahimi               (addr.IsVectorPlusScalar() && CPUHas(CPUFeatures::kSVE2)));
4965*f5c631daSSadaf Ebrahimi   if (addr.IsVectorPlusScalar()) {
4966*f5c631daSSadaf Ebrahimi     SVELd1VecScaHelper(zt, pg, addr, 0, /* is_signed = */ false);
4967*f5c631daSSadaf Ebrahimi   } else {
4968*f5c631daSSadaf Ebrahimi     SVELd1St1ScaImmHelper(zt,
4969*f5c631daSSadaf Ebrahimi                           pg,
4970*f5c631daSSadaf Ebrahimi                           addr,
4971*f5c631daSSadaf Ebrahimi                           LDNT1B_z_p_br_contiguous,
4972*f5c631daSSadaf Ebrahimi                           LDNT1B_z_p_bi_contiguous);
4973*f5c631daSSadaf Ebrahimi   }
4974*f5c631daSSadaf Ebrahimi }
4975*f5c631daSSadaf Ebrahimi 
ldnt1d(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)4976*f5c631daSSadaf Ebrahimi void Assembler::ldnt1d(const ZRegister& zt,
4977*f5c631daSSadaf Ebrahimi                        const PRegisterZ& pg,
4978*f5c631daSSadaf Ebrahimi                        const SVEMemOperand& addr) {
4979*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsPlainScalar() ||
4980*f5c631daSSadaf Ebrahimi               (addr.IsScalarPlusImmediate() && addr.IsMulVl()) ||
4981*f5c631daSSadaf Ebrahimi               (addr.IsScalarPlusScalar() && addr.IsEquivalentToLSL(3)) ||
4982*f5c631daSSadaf Ebrahimi               (addr.IsVectorPlusScalar() && CPUHas(CPUFeatures::kSVE2)));
4983*f5c631daSSadaf Ebrahimi   if (addr.IsVectorPlusScalar()) {
4984*f5c631daSSadaf Ebrahimi     SVELd1VecScaHelper(zt, pg, addr, 3, /* is_signed = */ false);
4985*f5c631daSSadaf Ebrahimi   } else {
4986*f5c631daSSadaf Ebrahimi     SVELd1St1ScaImmHelper(zt,
4987*f5c631daSSadaf Ebrahimi                           pg,
4988*f5c631daSSadaf Ebrahimi                           addr,
4989*f5c631daSSadaf Ebrahimi                           LDNT1D_z_p_br_contiguous,
4990*f5c631daSSadaf Ebrahimi                           LDNT1D_z_p_bi_contiguous);
4991*f5c631daSSadaf Ebrahimi   }
4992*f5c631daSSadaf Ebrahimi }
4993*f5c631daSSadaf Ebrahimi 
ldnt1h(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)4994*f5c631daSSadaf Ebrahimi void Assembler::ldnt1h(const ZRegister& zt,
4995*f5c631daSSadaf Ebrahimi                        const PRegisterZ& pg,
4996*f5c631daSSadaf Ebrahimi                        const SVEMemOperand& addr) {
4997*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsPlainScalar() ||
4998*f5c631daSSadaf Ebrahimi               (addr.IsScalarPlusImmediate() && addr.IsMulVl()) ||
4999*f5c631daSSadaf Ebrahimi               (addr.IsScalarPlusScalar() && addr.IsEquivalentToLSL(1)) ||
5000*f5c631daSSadaf Ebrahimi               (addr.IsVectorPlusScalar() && CPUHas(CPUFeatures::kSVE2)));
5001*f5c631daSSadaf Ebrahimi   if (addr.IsVectorPlusScalar()) {
5002*f5c631daSSadaf Ebrahimi     SVELd1VecScaHelper(zt, pg, addr, 1, /* is_signed = */ false);
5003*f5c631daSSadaf Ebrahimi   } else {
5004*f5c631daSSadaf Ebrahimi     SVELd1St1ScaImmHelper(zt,
5005*f5c631daSSadaf Ebrahimi                           pg,
5006*f5c631daSSadaf Ebrahimi                           addr,
5007*f5c631daSSadaf Ebrahimi                           LDNT1H_z_p_br_contiguous,
5008*f5c631daSSadaf Ebrahimi                           LDNT1H_z_p_bi_contiguous);
5009*f5c631daSSadaf Ebrahimi   }
5010*f5c631daSSadaf Ebrahimi }
5011*f5c631daSSadaf Ebrahimi 
ldnt1w(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)5012*f5c631daSSadaf Ebrahimi void Assembler::ldnt1w(const ZRegister& zt,
5013*f5c631daSSadaf Ebrahimi                        const PRegisterZ& pg,
5014*f5c631daSSadaf Ebrahimi                        const SVEMemOperand& addr) {
5015*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsPlainScalar() ||
5016*f5c631daSSadaf Ebrahimi               (addr.IsScalarPlusImmediate() && addr.IsMulVl()) ||
5017*f5c631daSSadaf Ebrahimi               (addr.IsScalarPlusScalar() && addr.IsEquivalentToLSL(2)) ||
5018*f5c631daSSadaf Ebrahimi               (addr.IsVectorPlusScalar() && CPUHas(CPUFeatures::kSVE2)));
5019*f5c631daSSadaf Ebrahimi   if (addr.IsVectorPlusScalar()) {
5020*f5c631daSSadaf Ebrahimi     SVELd1VecScaHelper(zt, pg, addr, 2, /* is_signed = */ false);
5021*f5c631daSSadaf Ebrahimi   } else {
5022*f5c631daSSadaf Ebrahimi     SVELd1St1ScaImmHelper(zt,
5023*f5c631daSSadaf Ebrahimi                           pg,
5024*f5c631daSSadaf Ebrahimi                           addr,
5025*f5c631daSSadaf Ebrahimi                           LDNT1W_z_p_br_contiguous,
5026*f5c631daSSadaf Ebrahimi                           LDNT1W_z_p_bi_contiguous);
5027*f5c631daSSadaf Ebrahimi   }
5028*f5c631daSSadaf Ebrahimi }
5029*f5c631daSSadaf Ebrahimi 
ldnt1sb(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)5030*f5c631daSSadaf Ebrahimi void Assembler::ldnt1sb(const ZRegister& zt,
5031*f5c631daSSadaf Ebrahimi                         const PRegisterZ& pg,
5032*f5c631daSSadaf Ebrahimi                         const SVEMemOperand& addr) {
5033*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsVectorPlusScalar() && CPUHas(CPUFeatures::kSVE2));
5034*f5c631daSSadaf Ebrahimi   SVELd1VecScaHelper(zt, pg, addr, 0, /* is_signed = */ true);
5035*f5c631daSSadaf Ebrahimi }
5036*f5c631daSSadaf Ebrahimi 
ldnt1sh(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)5037*f5c631daSSadaf Ebrahimi void Assembler::ldnt1sh(const ZRegister& zt,
5038*f5c631daSSadaf Ebrahimi                         const PRegisterZ& pg,
5039*f5c631daSSadaf Ebrahimi                         const SVEMemOperand& addr) {
5040*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsVectorPlusScalar() && CPUHas(CPUFeatures::kSVE2));
5041*f5c631daSSadaf Ebrahimi   SVELd1VecScaHelper(zt, pg, addr, 1, /* is_signed = */ true);
5042*f5c631daSSadaf Ebrahimi }
5043*f5c631daSSadaf Ebrahimi 
ldnt1sw(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)5044*f5c631daSSadaf Ebrahimi void Assembler::ldnt1sw(const ZRegister& zt,
5045*f5c631daSSadaf Ebrahimi                         const PRegisterZ& pg,
5046*f5c631daSSadaf Ebrahimi                         const SVEMemOperand& addr) {
5047*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsVectorPlusScalar() && CPUHas(CPUFeatures::kSVE2));
5048*f5c631daSSadaf Ebrahimi   SVELd1VecScaHelper(zt, pg, addr, 2, /* is_signed = */ true);
5049*f5c631daSSadaf Ebrahimi }
5050*f5c631daSSadaf Ebrahimi 
SVEMemOperandHelper(unsigned msize_in_bytes_log2,int num_regs,const SVEMemOperand & addr,bool is_load)5051*f5c631daSSadaf Ebrahimi Instr Assembler::SVEMemOperandHelper(unsigned msize_in_bytes_log2,
5052*f5c631daSSadaf Ebrahimi                                      int num_regs,
5053*f5c631daSSadaf Ebrahimi                                      const SVEMemOperand& addr,
5054*f5c631daSSadaf Ebrahimi                                      bool is_load) {
5055*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((num_regs >= 1) && (num_regs <= 4));
5056*f5c631daSSadaf Ebrahimi 
5057*f5c631daSSadaf Ebrahimi   Instr op = 0xfffffff;
5058*f5c631daSSadaf Ebrahimi   if (addr.IsScalarPlusImmediate()) {
5059*f5c631daSSadaf Ebrahimi     VIXL_ASSERT((addr.GetImmediateOffset() == 0) || addr.IsMulVl());
5060*f5c631daSSadaf Ebrahimi     int64_t imm = addr.GetImmediateOffset();
5061*f5c631daSSadaf Ebrahimi     VIXL_ASSERT((imm % num_regs) == 0);
5062*f5c631daSSadaf Ebrahimi     op = RnSP(addr.GetScalarBase()) | ImmField<19, 16>(imm / num_regs);
5063*f5c631daSSadaf Ebrahimi 
5064*f5c631daSSadaf Ebrahimi   } else if (addr.IsScalarPlusScalar()) {
5065*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(addr.GetScalarOffset().IsZero() ||
5066*f5c631daSSadaf Ebrahimi                 addr.IsEquivalentToLSL(msize_in_bytes_log2));
5067*f5c631daSSadaf Ebrahimi     op = RnSP(addr.GetScalarBase()) | Rm(addr.GetScalarOffset());
5068*f5c631daSSadaf Ebrahimi 
5069*f5c631daSSadaf Ebrahimi   } else if (addr.IsVectorPlusImmediate()) {
5070*f5c631daSSadaf Ebrahimi     ZRegister zn = addr.GetVectorBase();
5071*f5c631daSSadaf Ebrahimi     uint64_t imm = addr.GetImmediateOffset();
5072*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(num_regs == 1);
5073*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zn.IsLaneSizeS() || zn.IsLaneSizeD());
5074*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsMultiple(imm, (1 << msize_in_bytes_log2)));
5075*f5c631daSSadaf Ebrahimi     op = Rn(zn) | ImmUnsignedField<20, 16>(imm >> msize_in_bytes_log2);
5076*f5c631daSSadaf Ebrahimi   } else if (addr.IsVectorPlusScalar()) {
5077*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(addr.GetOffsetModifier() == NO_SVE_OFFSET_MODIFIER);
5078*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(addr.GetShiftAmount() == 0);
5079*f5c631daSSadaf Ebrahimi     ZRegister zn = addr.GetVectorBase();
5080*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zn.IsLaneSizeS() || zn.IsLaneSizeD());
5081*f5c631daSSadaf Ebrahimi     Register xm = addr.GetScalarOffset();
5082*f5c631daSSadaf Ebrahimi     op = Rn(zn) | Rm(xm);
5083*f5c631daSSadaf Ebrahimi   } else if (addr.IsScalarPlusVector()) {
5084*f5c631daSSadaf Ebrahimi     // We have to support several different addressing modes. Some instructions
5085*f5c631daSSadaf Ebrahimi     // support a subset of these, but the SVEMemOperand encoding is consistent.
5086*f5c631daSSadaf Ebrahimi     Register xn = addr.GetScalarBase();
5087*f5c631daSSadaf Ebrahimi     ZRegister zm = addr.GetVectorOffset();
5088*f5c631daSSadaf Ebrahimi     SVEOffsetModifier mod = addr.GetOffsetModifier();
5089*f5c631daSSadaf Ebrahimi     Instr modifier_bit = 1 << (is_load ? 22 : 14);
5090*f5c631daSSadaf Ebrahimi     Instr xs = (mod == SVE_SXTW) ? modifier_bit : 0;
5091*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(num_regs == 1);
5092*f5c631daSSadaf Ebrahimi 
5093*f5c631daSSadaf Ebrahimi     if (mod == SVE_LSL) {
5094*f5c631daSSadaf Ebrahimi       // 64-bit scaled offset:            [<Xn|SP>, <Zm>.D, LSL #<shift>]
5095*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(zm.IsLaneSizeD());
5096*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(addr.GetShiftAmount() == msize_in_bytes_log2);
5097*f5c631daSSadaf Ebrahimi     } else if (mod == NO_SVE_OFFSET_MODIFIER) {
5098*f5c631daSSadaf Ebrahimi       // 64-bit unscaled offset:          [<Xn|SP>, <Zm>.D]
5099*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(zm.IsLaneSizeD());
5100*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(addr.GetShiftAmount() == 0);
5101*f5c631daSSadaf Ebrahimi     } else {
5102*f5c631daSSadaf Ebrahimi       // 32-bit scaled offset:            [<Xn|SP>, <Zm>.S, <mod> #<shift>]
5103*f5c631daSSadaf Ebrahimi       // 32-bit unscaled offset:          [<Xn|SP>, <Zm>.S, <mod>]
5104*f5c631daSSadaf Ebrahimi       // 32-bit unpacked scaled offset:   [<Xn|SP>, <Zm>.D, <mod> #<shift>]
5105*f5c631daSSadaf Ebrahimi       // 32-bit unpacked unscaled offset: [<Xn|SP>, <Zm>.D, <mod>]
5106*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(zm.IsLaneSizeS() || zm.IsLaneSizeD());
5107*f5c631daSSadaf Ebrahimi       VIXL_ASSERT((mod == SVE_SXTW) || (mod == SVE_UXTW));
5108*f5c631daSSadaf Ebrahimi       VIXL_ASSERT((addr.GetShiftAmount() == 0) ||
5109*f5c631daSSadaf Ebrahimi                   (addr.GetShiftAmount() == msize_in_bytes_log2));
5110*f5c631daSSadaf Ebrahimi     }
5111*f5c631daSSadaf Ebrahimi 
5112*f5c631daSSadaf Ebrahimi     // The form itself is encoded in the instruction opcode.
5113*f5c631daSSadaf Ebrahimi     op = RnSP(xn) | Rm(zm) | xs;
5114*f5c631daSSadaf Ebrahimi   } else {
5115*f5c631daSSadaf Ebrahimi     VIXL_UNIMPLEMENTED();
5116*f5c631daSSadaf Ebrahimi   }
5117*f5c631daSSadaf Ebrahimi 
5118*f5c631daSSadaf Ebrahimi   return op;
5119*f5c631daSSadaf Ebrahimi }
5120*f5c631daSSadaf Ebrahimi 
5121*f5c631daSSadaf Ebrahimi // SVEMemStore.
5122*f5c631daSSadaf Ebrahimi 
SVESt1Helper(unsigned msize_in_bytes_log2,const ZRegister & zt,const PRegister & pg,const SVEMemOperand & addr)5123*f5c631daSSadaf Ebrahimi void Assembler::SVESt1Helper(unsigned msize_in_bytes_log2,
5124*f5c631daSSadaf Ebrahimi                              const ZRegister& zt,
5125*f5c631daSSadaf Ebrahimi                              const PRegister& pg,
5126*f5c631daSSadaf Ebrahimi                              const SVEMemOperand& addr) {
5127*f5c631daSSadaf Ebrahimi   if (addr.IsScalarPlusScalar()) {
5128*f5c631daSSadaf Ebrahimi     // Rm must not be xzr.
5129*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(!addr.GetScalarOffset().IsZero());
5130*f5c631daSSadaf Ebrahimi   }
5131*f5c631daSSadaf Ebrahimi 
5132*f5c631daSSadaf Ebrahimi   if (addr.IsScatterGather()) {
5133*f5c631daSSadaf Ebrahimi     bool is_load = false;
5134*f5c631daSSadaf Ebrahimi     bool is_signed = false;
5135*f5c631daSSadaf Ebrahimi     bool is_ff = false;
5136*f5c631daSSadaf Ebrahimi     SVEScatterGatherHelper(msize_in_bytes_log2,
5137*f5c631daSSadaf Ebrahimi                            zt,
5138*f5c631daSSadaf Ebrahimi                            pg,
5139*f5c631daSSadaf Ebrahimi                            addr,
5140*f5c631daSSadaf Ebrahimi                            is_load,
5141*f5c631daSSadaf Ebrahimi                            is_signed,
5142*f5c631daSSadaf Ebrahimi                            is_ff);
5143*f5c631daSSadaf Ebrahimi     return;
5144*f5c631daSSadaf Ebrahimi   }
5145*f5c631daSSadaf Ebrahimi 
5146*f5c631daSSadaf Ebrahimi   Instr op;
5147*f5c631daSSadaf Ebrahimi   if (addr.IsScalarPlusImmediate()) {
5148*f5c631daSSadaf Ebrahimi     op = SVEContiguousStore_ScalarPlusImmFixed;
5149*f5c631daSSadaf Ebrahimi   } else if (addr.IsScalarPlusScalar()) {
5150*f5c631daSSadaf Ebrahimi     op = SVEContiguousStore_ScalarPlusScalarFixed;
5151*f5c631daSSadaf Ebrahimi   } else {
5152*f5c631daSSadaf Ebrahimi     VIXL_UNIMPLEMENTED();
5153*f5c631daSSadaf Ebrahimi     op = 0xffffffff;
5154*f5c631daSSadaf Ebrahimi   }
5155*f5c631daSSadaf Ebrahimi   SVELdSt1Helper(msize_in_bytes_log2, zt, pg, addr, false, op);
5156*f5c631daSSadaf Ebrahimi }
5157*f5c631daSSadaf Ebrahimi 
SVESt234Helper(int num_regs,const ZRegister & zt1,const PRegister & pg,const SVEMemOperand & addr)5158*f5c631daSSadaf Ebrahimi void Assembler::SVESt234Helper(int num_regs,
5159*f5c631daSSadaf Ebrahimi                                const ZRegister& zt1,
5160*f5c631daSSadaf Ebrahimi                                const PRegister& pg,
5161*f5c631daSSadaf Ebrahimi                                const SVEMemOperand& addr) {
5162*f5c631daSSadaf Ebrahimi   if (addr.IsScalarPlusScalar()) {
5163*f5c631daSSadaf Ebrahimi     // Rm must not be xzr.
5164*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(!addr.GetScalarOffset().IsZero());
5165*f5c631daSSadaf Ebrahimi   }
5166*f5c631daSSadaf Ebrahimi 
5167*f5c631daSSadaf Ebrahimi   Instr op;
5168*f5c631daSSadaf Ebrahimi   if (addr.IsScalarPlusImmediate()) {
5169*f5c631daSSadaf Ebrahimi     op = SVEStoreMultipleStructures_ScalarPlusImmFixed;
5170*f5c631daSSadaf Ebrahimi   } else if (addr.IsScalarPlusScalar()) {
5171*f5c631daSSadaf Ebrahimi     op = SVEStoreMultipleStructures_ScalarPlusScalarFixed;
5172*f5c631daSSadaf Ebrahimi   } else {
5173*f5c631daSSadaf Ebrahimi     // These instructions don't support any other addressing modes.
5174*f5c631daSSadaf Ebrahimi     VIXL_ABORT();
5175*f5c631daSSadaf Ebrahimi   }
5176*f5c631daSSadaf Ebrahimi   SVELdSt234Helper(num_regs, zt1, pg, addr, op);
5177*f5c631daSSadaf Ebrahimi }
5178*f5c631daSSadaf Ebrahimi 
5179*f5c631daSSadaf Ebrahimi #define VIXL_DEFINE_ST1(MSZ, LANE_SIZE)                           \
5180*f5c631daSSadaf Ebrahimi   void Assembler::st1##MSZ(const ZRegister& zt,                   \
5181*f5c631daSSadaf Ebrahimi                            const PRegister& pg,                   \
5182*f5c631daSSadaf Ebrahimi                            const SVEMemOperand& addr) {           \
5183*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));                       \
5184*f5c631daSSadaf Ebrahimi     SVESt1Helper(k##LANE_SIZE##RegSizeInBytesLog2, zt, pg, addr); \
5185*f5c631daSSadaf Ebrahimi   }
5186*f5c631daSSadaf Ebrahimi #define VIXL_DEFINE_ST2(MSZ, LANE_SIZE)                 \
5187*f5c631daSSadaf Ebrahimi   void Assembler::st2##MSZ(const ZRegister& zt1,        \
5188*f5c631daSSadaf Ebrahimi                            const ZRegister& zt2,        \
5189*f5c631daSSadaf Ebrahimi                            const PRegister& pg,         \
5190*f5c631daSSadaf Ebrahimi                            const SVEMemOperand& addr) { \
5191*f5c631daSSadaf Ebrahimi     USE(zt2);                                           \
5192*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));             \
5193*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(AreConsecutive(zt1, zt2));              \
5194*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(AreSameFormat(zt1, zt2));               \
5195*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zt1.IsLaneSize##LANE_SIZE());           \
5196*f5c631daSSadaf Ebrahimi     SVESt234Helper(2, zt1, pg, addr);                   \
5197*f5c631daSSadaf Ebrahimi   }
5198*f5c631daSSadaf Ebrahimi #define VIXL_DEFINE_ST3(MSZ, LANE_SIZE)                 \
5199*f5c631daSSadaf Ebrahimi   void Assembler::st3##MSZ(const ZRegister& zt1,        \
5200*f5c631daSSadaf Ebrahimi                            const ZRegister& zt2,        \
5201*f5c631daSSadaf Ebrahimi                            const ZRegister& zt3,        \
5202*f5c631daSSadaf Ebrahimi                            const PRegister& pg,         \
5203*f5c631daSSadaf Ebrahimi                            const SVEMemOperand& addr) { \
5204*f5c631daSSadaf Ebrahimi     USE(zt2, zt3);                                      \
5205*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));             \
5206*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(AreConsecutive(zt1, zt2, zt3));         \
5207*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(AreSameFormat(zt1, zt2, zt3));          \
5208*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zt1.IsLaneSize##LANE_SIZE());           \
5209*f5c631daSSadaf Ebrahimi     SVESt234Helper(3, zt1, pg, addr);                   \
5210*f5c631daSSadaf Ebrahimi   }
5211*f5c631daSSadaf Ebrahimi #define VIXL_DEFINE_ST4(MSZ, LANE_SIZE)                 \
5212*f5c631daSSadaf Ebrahimi   void Assembler::st4##MSZ(const ZRegister& zt1,        \
5213*f5c631daSSadaf Ebrahimi                            const ZRegister& zt2,        \
5214*f5c631daSSadaf Ebrahimi                            const ZRegister& zt3,        \
5215*f5c631daSSadaf Ebrahimi                            const ZRegister& zt4,        \
5216*f5c631daSSadaf Ebrahimi                            const PRegister& pg,         \
5217*f5c631daSSadaf Ebrahimi                            const SVEMemOperand& addr) { \
5218*f5c631daSSadaf Ebrahimi     USE(zt2, zt3, zt4);                                 \
5219*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));             \
5220*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(AreConsecutive(zt1, zt2, zt3, zt4));    \
5221*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(AreSameFormat(zt1, zt2, zt3, zt4));     \
5222*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zt1.IsLaneSize##LANE_SIZE());           \
5223*f5c631daSSadaf Ebrahimi     SVESt234Helper(4, zt1, pg, addr);                   \
5224*f5c631daSSadaf Ebrahimi   }
5225*f5c631daSSadaf Ebrahimi 
5226*f5c631daSSadaf Ebrahimi VIXL_SVE_LOAD_STORE_VARIANT_LIST(VIXL_DEFINE_ST1)
VIXL_SVE_LOAD_STORE_VARIANT_LIST(VIXL_DEFINE_ST2)5227*f5c631daSSadaf Ebrahimi VIXL_SVE_LOAD_STORE_VARIANT_LIST(VIXL_DEFINE_ST2)
5228*f5c631daSSadaf Ebrahimi VIXL_SVE_LOAD_STORE_VARIANT_LIST(VIXL_DEFINE_ST3)
5229*f5c631daSSadaf Ebrahimi VIXL_SVE_LOAD_STORE_VARIANT_LIST(VIXL_DEFINE_ST4)
5230*f5c631daSSadaf Ebrahimi 
5231*f5c631daSSadaf Ebrahimi void Assembler::stnt1b(const ZRegister& zt,
5232*f5c631daSSadaf Ebrahimi                        const PRegister& pg,
5233*f5c631daSSadaf Ebrahimi                        const SVEMemOperand& addr) {
5234*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsPlainScalar() ||
5235*f5c631daSSadaf Ebrahimi               (addr.IsScalarPlusImmediate() && addr.IsMulVl()) ||
5236*f5c631daSSadaf Ebrahimi               (addr.IsScalarPlusScalar() && addr.IsEquivalentToLSL(0)) ||
5237*f5c631daSSadaf Ebrahimi               (addr.IsVectorPlusScalar() && CPUHas(CPUFeatures::kSVE2)));
5238*f5c631daSSadaf Ebrahimi   if (addr.IsVectorPlusScalar()) {
5239*f5c631daSSadaf Ebrahimi     SVESt1VecScaHelper(zt, pg, addr, 0);
5240*f5c631daSSadaf Ebrahimi   } else {
5241*f5c631daSSadaf Ebrahimi     SVELd1St1ScaImmHelper(zt,
5242*f5c631daSSadaf Ebrahimi                           pg,
5243*f5c631daSSadaf Ebrahimi                           addr,
5244*f5c631daSSadaf Ebrahimi                           STNT1B_z_p_br_contiguous,
5245*f5c631daSSadaf Ebrahimi                           STNT1B_z_p_bi_contiguous);
5246*f5c631daSSadaf Ebrahimi   }
5247*f5c631daSSadaf Ebrahimi }
5248*f5c631daSSadaf Ebrahimi 
stnt1d(const ZRegister & zt,const PRegister & pg,const SVEMemOperand & addr)5249*f5c631daSSadaf Ebrahimi void Assembler::stnt1d(const ZRegister& zt,
5250*f5c631daSSadaf Ebrahimi                        const PRegister& pg,
5251*f5c631daSSadaf Ebrahimi                        const SVEMemOperand& addr) {
5252*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsPlainScalar() ||
5253*f5c631daSSadaf Ebrahimi               (addr.IsScalarPlusImmediate() && addr.IsMulVl()) ||
5254*f5c631daSSadaf Ebrahimi               (addr.IsScalarPlusScalar() && addr.IsEquivalentToLSL(3)) ||
5255*f5c631daSSadaf Ebrahimi               (addr.IsVectorPlusScalar() && CPUHas(CPUFeatures::kSVE2)));
5256*f5c631daSSadaf Ebrahimi   if (addr.IsVectorPlusScalar()) {
5257*f5c631daSSadaf Ebrahimi     SVESt1VecScaHelper(zt, pg, addr, 3);
5258*f5c631daSSadaf Ebrahimi   } else {
5259*f5c631daSSadaf Ebrahimi     SVELd1St1ScaImmHelper(zt,
5260*f5c631daSSadaf Ebrahimi                           pg,
5261*f5c631daSSadaf Ebrahimi                           addr,
5262*f5c631daSSadaf Ebrahimi                           STNT1D_z_p_br_contiguous,
5263*f5c631daSSadaf Ebrahimi                           STNT1D_z_p_bi_contiguous);
5264*f5c631daSSadaf Ebrahimi   }
5265*f5c631daSSadaf Ebrahimi }
5266*f5c631daSSadaf Ebrahimi 
stnt1h(const ZRegister & zt,const PRegister & pg,const SVEMemOperand & addr)5267*f5c631daSSadaf Ebrahimi void Assembler::stnt1h(const ZRegister& zt,
5268*f5c631daSSadaf Ebrahimi                        const PRegister& pg,
5269*f5c631daSSadaf Ebrahimi                        const SVEMemOperand& addr) {
5270*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsPlainScalar() ||
5271*f5c631daSSadaf Ebrahimi               (addr.IsScalarPlusImmediate() && addr.IsMulVl()) ||
5272*f5c631daSSadaf Ebrahimi               (addr.IsScalarPlusScalar() && addr.IsEquivalentToLSL(1)) ||
5273*f5c631daSSadaf Ebrahimi               (addr.IsVectorPlusScalar() && CPUHas(CPUFeatures::kSVE2)));
5274*f5c631daSSadaf Ebrahimi   if (addr.IsVectorPlusScalar()) {
5275*f5c631daSSadaf Ebrahimi     SVESt1VecScaHelper(zt, pg, addr, 1);
5276*f5c631daSSadaf Ebrahimi   } else {
5277*f5c631daSSadaf Ebrahimi     SVELd1St1ScaImmHelper(zt,
5278*f5c631daSSadaf Ebrahimi                           pg,
5279*f5c631daSSadaf Ebrahimi                           addr,
5280*f5c631daSSadaf Ebrahimi                           STNT1H_z_p_br_contiguous,
5281*f5c631daSSadaf Ebrahimi                           STNT1H_z_p_bi_contiguous);
5282*f5c631daSSadaf Ebrahimi   }
5283*f5c631daSSadaf Ebrahimi }
5284*f5c631daSSadaf Ebrahimi 
stnt1w(const ZRegister & zt,const PRegister & pg,const SVEMemOperand & addr)5285*f5c631daSSadaf Ebrahimi void Assembler::stnt1w(const ZRegister& zt,
5286*f5c631daSSadaf Ebrahimi                        const PRegister& pg,
5287*f5c631daSSadaf Ebrahimi                        const SVEMemOperand& addr) {
5288*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsPlainScalar() ||
5289*f5c631daSSadaf Ebrahimi               (addr.IsScalarPlusImmediate() && addr.IsMulVl()) ||
5290*f5c631daSSadaf Ebrahimi               (addr.IsScalarPlusScalar() && addr.IsEquivalentToLSL(2)) ||
5291*f5c631daSSadaf Ebrahimi               (addr.IsVectorPlusScalar() && CPUHas(CPUFeatures::kSVE2)));
5292*f5c631daSSadaf Ebrahimi   if (addr.IsVectorPlusScalar()) {
5293*f5c631daSSadaf Ebrahimi     SVESt1VecScaHelper(zt, pg, addr, 2);
5294*f5c631daSSadaf Ebrahimi   } else {
5295*f5c631daSSadaf Ebrahimi     SVELd1St1ScaImmHelper(zt,
5296*f5c631daSSadaf Ebrahimi                           pg,
5297*f5c631daSSadaf Ebrahimi                           addr,
5298*f5c631daSSadaf Ebrahimi                           STNT1W_z_p_br_contiguous,
5299*f5c631daSSadaf Ebrahimi                           STNT1W_z_p_bi_contiguous);
5300*f5c631daSSadaf Ebrahimi   }
5301*f5c631daSSadaf Ebrahimi }
5302*f5c631daSSadaf Ebrahimi 
str(const CPURegister & rt,const SVEMemOperand & addr)5303*f5c631daSSadaf Ebrahimi void Assembler::str(const CPURegister& rt, const SVEMemOperand& addr) {
5304*f5c631daSSadaf Ebrahimi   // STR <Pt/Zt>, [<Xn|SP>{, #<imm>, MUL VL}]
5305*f5c631daSSadaf Ebrahimi 
5306*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5307*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(rt.IsPRegister() || rt.IsZRegister());
5308*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(addr.IsPlainScalar() ||
5309*f5c631daSSadaf Ebrahimi               (addr.IsScalarPlusImmediate() &&
5310*f5c631daSSadaf Ebrahimi                (addr.GetOffsetModifier() == SVE_MUL_VL)));
5311*f5c631daSSadaf Ebrahimi   int64_t imm9 = addr.GetImmediateOffset();
5312*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(IsInt9(imm9));
5313*f5c631daSSadaf Ebrahimi   Instr imm9l = ExtractUnsignedBitfield32(2, 0, imm9) << 10;
5314*f5c631daSSadaf Ebrahimi   Instr imm9h = ExtractUnsignedBitfield32(8, 3, imm9) << 16;
5315*f5c631daSSadaf Ebrahimi 
5316*f5c631daSSadaf Ebrahimi   Instr op = STR_z_bi;
5317*f5c631daSSadaf Ebrahimi   if (rt.IsPRegister()) {
5318*f5c631daSSadaf Ebrahimi     op = STR_p_bi;
5319*f5c631daSSadaf Ebrahimi   }
5320*f5c631daSSadaf Ebrahimi   Emit(op | Rt(rt) | RnSP(addr.GetScalarBase()) | imm9h | imm9l);
5321*f5c631daSSadaf Ebrahimi }
5322*f5c631daSSadaf Ebrahimi 
5323*f5c631daSSadaf Ebrahimi // SVEMulIndex.
5324*f5c631daSSadaf Ebrahimi 
sdot(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm,int index)5325*f5c631daSSadaf Ebrahimi void Assembler::sdot(const ZRegister& zda,
5326*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
5327*f5c631daSSadaf Ebrahimi                      const ZRegister& zm,
5328*f5c631daSSadaf Ebrahimi                      int index) {
5329*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5330*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 4));
5331*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
5332*f5c631daSSadaf Ebrahimi 
5333*f5c631daSSadaf Ebrahimi   Instr op = 0xffffffff;
5334*f5c631daSSadaf Ebrahimi   switch (zda.GetLaneSizeInBits()) {
5335*f5c631daSSadaf Ebrahimi     case kSRegSize:
5336*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(IsUint2(index));
5337*f5c631daSSadaf Ebrahimi       op = SDOT_z_zzzi_s | Rx<18, 16>(zm) | (index << 19) | Rd(zda) | Rn(zn);
5338*f5c631daSSadaf Ebrahimi       break;
5339*f5c631daSSadaf Ebrahimi     case kDRegSize:
5340*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(IsUint1(index));
5341*f5c631daSSadaf Ebrahimi       op = SDOT_z_zzzi_d | Rx<19, 16>(zm) | (index << 20) | Rd(zda) | Rn(zn);
5342*f5c631daSSadaf Ebrahimi       break;
5343*f5c631daSSadaf Ebrahimi     default:
5344*f5c631daSSadaf Ebrahimi       VIXL_UNIMPLEMENTED();
5345*f5c631daSSadaf Ebrahimi       break;
5346*f5c631daSSadaf Ebrahimi   }
5347*f5c631daSSadaf Ebrahimi 
5348*f5c631daSSadaf Ebrahimi   Emit(op);
5349*f5c631daSSadaf Ebrahimi }
5350*f5c631daSSadaf Ebrahimi 
udot(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm,int index)5351*f5c631daSSadaf Ebrahimi void Assembler::udot(const ZRegister& zda,
5352*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
5353*f5c631daSSadaf Ebrahimi                      const ZRegister& zm,
5354*f5c631daSSadaf Ebrahimi                      int index) {
5355*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5356*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 4));
5357*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
5358*f5c631daSSadaf Ebrahimi 
5359*f5c631daSSadaf Ebrahimi   Instr op = 0xffffffff;
5360*f5c631daSSadaf Ebrahimi   switch (zda.GetLaneSizeInBits()) {
5361*f5c631daSSadaf Ebrahimi     case kSRegSize:
5362*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(IsUint2(index));
5363*f5c631daSSadaf Ebrahimi       op = UDOT_z_zzzi_s | Rx<18, 16>(zm) | (index << 19) | Rd(zda) | Rn(zn);
5364*f5c631daSSadaf Ebrahimi       break;
5365*f5c631daSSadaf Ebrahimi     case kDRegSize:
5366*f5c631daSSadaf Ebrahimi       VIXL_ASSERT(IsUint1(index));
5367*f5c631daSSadaf Ebrahimi       op = UDOT_z_zzzi_d | Rx<19, 16>(zm) | (index << 20) | Rd(zda) | Rn(zn);
5368*f5c631daSSadaf Ebrahimi       break;
5369*f5c631daSSadaf Ebrahimi     default:
5370*f5c631daSSadaf Ebrahimi       VIXL_UNIMPLEMENTED();
5371*f5c631daSSadaf Ebrahimi       break;
5372*f5c631daSSadaf Ebrahimi   }
5373*f5c631daSSadaf Ebrahimi 
5374*f5c631daSSadaf Ebrahimi   Emit(op);
5375*f5c631daSSadaf Ebrahimi }
5376*f5c631daSSadaf Ebrahimi 
5377*f5c631daSSadaf Ebrahimi // SVEPartitionBreak.
5378*f5c631daSSadaf Ebrahimi 
brka(const PRegisterWithLaneSize & pd,const PRegister & pg,const PRegisterWithLaneSize & pn)5379*f5c631daSSadaf Ebrahimi void Assembler::brka(const PRegisterWithLaneSize& pd,
5380*f5c631daSSadaf Ebrahimi                      const PRegister& pg,
5381*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pn) {
5382*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5383*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pg.IsMerging() || pg.IsZeroing());
5384*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pd.IsLaneSizeB() && pn.IsLaneSizeB());
5385*f5c631daSSadaf Ebrahimi 
5386*f5c631daSSadaf Ebrahimi   Instr m = pg.IsMerging() ? 0x00000010 : 0x00000000;
5387*f5c631daSSadaf Ebrahimi   Emit(BRKA_p_p_p | Pd(pd) | Pg<13, 10>(pg) | m | Pn(pn));
5388*f5c631daSSadaf Ebrahimi }
5389*f5c631daSSadaf Ebrahimi 
brkas(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn)5390*f5c631daSSadaf Ebrahimi void Assembler::brkas(const PRegisterWithLaneSize& pd,
5391*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
5392*f5c631daSSadaf Ebrahimi                       const PRegisterWithLaneSize& pn) {
5393*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5394*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pd.IsLaneSizeB() && pn.IsLaneSizeB());
5395*f5c631daSSadaf Ebrahimi 
5396*f5c631daSSadaf Ebrahimi   Emit(BRKAS_p_p_p_z | Pd(pd) | Pg<13, 10>(pg) | Pn(pn));
5397*f5c631daSSadaf Ebrahimi }
5398*f5c631daSSadaf Ebrahimi 
brkb(const PRegisterWithLaneSize & pd,const PRegister & pg,const PRegisterWithLaneSize & pn)5399*f5c631daSSadaf Ebrahimi void Assembler::brkb(const PRegisterWithLaneSize& pd,
5400*f5c631daSSadaf Ebrahimi                      const PRegister& pg,
5401*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pn) {
5402*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5403*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pg.IsMerging() || pg.IsZeroing());
5404*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pd.IsLaneSizeB() && pn.IsLaneSizeB());
5405*f5c631daSSadaf Ebrahimi 
5406*f5c631daSSadaf Ebrahimi   Instr m = pg.IsMerging() ? 0x00000010 : 0x00000000;
5407*f5c631daSSadaf Ebrahimi   Emit(BRKB_p_p_p | Pd(pd) | Pg<13, 10>(pg) | m | Pn(pn));
5408*f5c631daSSadaf Ebrahimi }
5409*f5c631daSSadaf Ebrahimi 
brkbs(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn)5410*f5c631daSSadaf Ebrahimi void Assembler::brkbs(const PRegisterWithLaneSize& pd,
5411*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
5412*f5c631daSSadaf Ebrahimi                       const PRegisterWithLaneSize& pn) {
5413*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5414*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pd.IsLaneSizeB() && pn.IsLaneSizeB());
5415*f5c631daSSadaf Ebrahimi 
5416*f5c631daSSadaf Ebrahimi   Emit(BRKBS_p_p_p_z | Pd(pd) | Pg<13, 10>(pg) | Pn(pn));
5417*f5c631daSSadaf Ebrahimi }
5418*f5c631daSSadaf Ebrahimi 
brkn(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)5419*f5c631daSSadaf Ebrahimi void Assembler::brkn(const PRegisterWithLaneSize& pd,
5420*f5c631daSSadaf Ebrahimi                      const PRegisterZ& pg,
5421*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pn,
5422*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pm) {
5423*f5c631daSSadaf Ebrahimi   USE(pm);
5424*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5425*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pd.IsLaneSizeB() && pn.IsLaneSizeB());
5426*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pd.Is(pm));
5427*f5c631daSSadaf Ebrahimi 
5428*f5c631daSSadaf Ebrahimi   Emit(BRKN_p_p_pp | Pd(pd) | Pg<13, 10>(pg) | Pn(pn));
5429*f5c631daSSadaf Ebrahimi }
5430*f5c631daSSadaf Ebrahimi 
brkns(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)5431*f5c631daSSadaf Ebrahimi void Assembler::brkns(const PRegisterWithLaneSize& pd,
5432*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
5433*f5c631daSSadaf Ebrahimi                       const PRegisterWithLaneSize& pn,
5434*f5c631daSSadaf Ebrahimi                       const PRegisterWithLaneSize& pm) {
5435*f5c631daSSadaf Ebrahimi   USE(pm);
5436*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5437*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pd.IsLaneSizeB() && pn.IsLaneSizeB());
5438*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pd.Is(pm));
5439*f5c631daSSadaf Ebrahimi 
5440*f5c631daSSadaf Ebrahimi   Emit(BRKNS_p_p_pp | Pd(pd) | Pg<13, 10>(pg) | Pn(pn));
5441*f5c631daSSadaf Ebrahimi }
5442*f5c631daSSadaf Ebrahimi 
5443*f5c631daSSadaf Ebrahimi // SVEPermutePredicate.
5444*f5c631daSSadaf Ebrahimi 
punpkhi(const PRegisterWithLaneSize & pd,const PRegisterWithLaneSize & pn)5445*f5c631daSSadaf Ebrahimi void Assembler::punpkhi(const PRegisterWithLaneSize& pd,
5446*f5c631daSSadaf Ebrahimi                         const PRegisterWithLaneSize& pn) {
5447*f5c631daSSadaf Ebrahimi   // PUNPKHI <Pd>.H, <Pn>.B
5448*f5c631daSSadaf Ebrahimi   //  0000 0101 0011 0001 0100 000. ...0 ....
5449*f5c631daSSadaf Ebrahimi   //  H<16> = 1 | Pn<8:5> | Pd<3:0>
5450*f5c631daSSadaf Ebrahimi 
5451*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5452*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pd.IsLaneSizeH());
5453*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pn.IsLaneSizeB());
5454*f5c631daSSadaf Ebrahimi 
5455*f5c631daSSadaf Ebrahimi   Emit(PUNPKHI_p_p | Pd(pd) | Pn(pn));
5456*f5c631daSSadaf Ebrahimi }
5457*f5c631daSSadaf Ebrahimi 
punpklo(const PRegisterWithLaneSize & pd,const PRegisterWithLaneSize & pn)5458*f5c631daSSadaf Ebrahimi void Assembler::punpklo(const PRegisterWithLaneSize& pd,
5459*f5c631daSSadaf Ebrahimi                         const PRegisterWithLaneSize& pn) {
5460*f5c631daSSadaf Ebrahimi   // PUNPKLO <Pd>.H, <Pn>.B
5461*f5c631daSSadaf Ebrahimi   //  0000 0101 0011 0000 0100 000. ...0 ....
5462*f5c631daSSadaf Ebrahimi   //  H<16> = 0 | Pn<8:5> | Pd<3:0>
5463*f5c631daSSadaf Ebrahimi 
5464*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5465*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pd.IsLaneSizeH());
5466*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pn.IsLaneSizeB());
5467*f5c631daSSadaf Ebrahimi 
5468*f5c631daSSadaf Ebrahimi   Emit(PUNPKLO_p_p | Pd(pd) | Pn(pn));
5469*f5c631daSSadaf Ebrahimi }
5470*f5c631daSSadaf Ebrahimi 
rev(const PRegisterWithLaneSize & pd,const PRegisterWithLaneSize & pn)5471*f5c631daSSadaf Ebrahimi void Assembler::rev(const PRegisterWithLaneSize& pd,
5472*f5c631daSSadaf Ebrahimi                     const PRegisterWithLaneSize& pn) {
5473*f5c631daSSadaf Ebrahimi   // REV <Pd>.<T>, <Pn>.<T>
5474*f5c631daSSadaf Ebrahimi   //  0000 0101 ..11 0100 0100 000. ...0 ....
5475*f5c631daSSadaf Ebrahimi   //  size<23:22> | Pn<8:5> | Pd<3:0>
5476*f5c631daSSadaf Ebrahimi 
5477*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5478*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, pn));
5479*f5c631daSSadaf Ebrahimi 
5480*f5c631daSSadaf Ebrahimi   Emit(REV_p_p | SVESize(pd) | Pd(pd) | Rx<8, 5>(pn));
5481*f5c631daSSadaf Ebrahimi }
5482*f5c631daSSadaf Ebrahimi 
trn1(const PRegisterWithLaneSize & pd,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)5483*f5c631daSSadaf Ebrahimi void Assembler::trn1(const PRegisterWithLaneSize& pd,
5484*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pn,
5485*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pm) {
5486*f5c631daSSadaf Ebrahimi   // TRN1 <Pd>.<T>, <Pn>.<T>, <Pm>.<T>
5487*f5c631daSSadaf Ebrahimi   //  0000 0101 ..10 .... 0101 000. ...0 ....
5488*f5c631daSSadaf Ebrahimi   //  size<23:22> | Pm<19:16> | opc<12:11> = 10 | H<10> = 0 | Pn<8:5> | Pd<3:0>
5489*f5c631daSSadaf Ebrahimi 
5490*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5491*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, pn, pm));
5492*f5c631daSSadaf Ebrahimi 
5493*f5c631daSSadaf Ebrahimi   Emit(TRN1_p_pp | SVESize(pd) | Pd(pd) | Pn(pn) | Pm(pm));
5494*f5c631daSSadaf Ebrahimi }
5495*f5c631daSSadaf Ebrahimi 
trn2(const PRegisterWithLaneSize & pd,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)5496*f5c631daSSadaf Ebrahimi void Assembler::trn2(const PRegisterWithLaneSize& pd,
5497*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pn,
5498*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pm) {
5499*f5c631daSSadaf Ebrahimi   // TRN2 <Pd>.<T>, <Pn>.<T>, <Pm>.<T>
5500*f5c631daSSadaf Ebrahimi   //  0000 0101 ..10 .... 0101 010. ...0 ....
5501*f5c631daSSadaf Ebrahimi   //  size<23:22> | Pm<19:16> | opc<12:11> = 10 | H<10> = 1 | Pn<8:5> | Pd<3:0>
5502*f5c631daSSadaf Ebrahimi 
5503*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5504*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, pn, pm));
5505*f5c631daSSadaf Ebrahimi 
5506*f5c631daSSadaf Ebrahimi   Emit(TRN2_p_pp | SVESize(pd) | Pd(pd) | Pn(pn) | Pm(pm));
5507*f5c631daSSadaf Ebrahimi }
5508*f5c631daSSadaf Ebrahimi 
uzp1(const PRegisterWithLaneSize & pd,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)5509*f5c631daSSadaf Ebrahimi void Assembler::uzp1(const PRegisterWithLaneSize& pd,
5510*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pn,
5511*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pm) {
5512*f5c631daSSadaf Ebrahimi   // UZP1 <Pd>.<T>, <Pn>.<T>, <Pm>.<T>
5513*f5c631daSSadaf Ebrahimi   //  0000 0101 ..10 .... 0100 100. ...0 ....
5514*f5c631daSSadaf Ebrahimi   //  size<23:22> | Pm<19:16> | opc<12:11> = 01 | H<10> = 0 | Pn<8:5> | Pd<3:0>
5515*f5c631daSSadaf Ebrahimi 
5516*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5517*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, pn, pm));
5518*f5c631daSSadaf Ebrahimi 
5519*f5c631daSSadaf Ebrahimi   Emit(UZP1_p_pp | SVESize(pd) | Pd(pd) | Pn(pn) | Pm(pm));
5520*f5c631daSSadaf Ebrahimi }
5521*f5c631daSSadaf Ebrahimi 
uzp2(const PRegisterWithLaneSize & pd,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)5522*f5c631daSSadaf Ebrahimi void Assembler::uzp2(const PRegisterWithLaneSize& pd,
5523*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pn,
5524*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pm) {
5525*f5c631daSSadaf Ebrahimi   // UZP2 <Pd>.<T>, <Pn>.<T>, <Pm>.<T>
5526*f5c631daSSadaf Ebrahimi   //  0000 0101 ..10 .... 0100 110. ...0 ....
5527*f5c631daSSadaf Ebrahimi   //  size<23:22> | Pm<19:16> | opc<12:11> = 01 | H<10> = 1 | Pn<8:5> | Pd<3:0>
5528*f5c631daSSadaf Ebrahimi 
5529*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5530*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, pn, pm));
5531*f5c631daSSadaf Ebrahimi 
5532*f5c631daSSadaf Ebrahimi   Emit(UZP2_p_pp | SVESize(pd) | Pd(pd) | Pn(pn) | Pm(pm));
5533*f5c631daSSadaf Ebrahimi }
5534*f5c631daSSadaf Ebrahimi 
zip1(const PRegisterWithLaneSize & pd,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)5535*f5c631daSSadaf Ebrahimi void Assembler::zip1(const PRegisterWithLaneSize& pd,
5536*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pn,
5537*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pm) {
5538*f5c631daSSadaf Ebrahimi   // ZIP1 <Pd>.<T>, <Pn>.<T>, <Pm>.<T>
5539*f5c631daSSadaf Ebrahimi   //  0000 0101 ..10 .... 0100 000. ...0 ....
5540*f5c631daSSadaf Ebrahimi   //  size<23:22> | Pm<19:16> | opc<12:11> = 00 | H<10> = 0 | Pn<8:5> | Pd<3:0>
5541*f5c631daSSadaf Ebrahimi 
5542*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5543*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, pn, pm));
5544*f5c631daSSadaf Ebrahimi 
5545*f5c631daSSadaf Ebrahimi   Emit(ZIP1_p_pp | SVESize(pd) | Pd(pd) | Pn(pn) | Pm(pm));
5546*f5c631daSSadaf Ebrahimi }
5547*f5c631daSSadaf Ebrahimi 
zip2(const PRegisterWithLaneSize & pd,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)5548*f5c631daSSadaf Ebrahimi void Assembler::zip2(const PRegisterWithLaneSize& pd,
5549*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pn,
5550*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pm) {
5551*f5c631daSSadaf Ebrahimi   // ZIP2 <Pd>.<T>, <Pn>.<T>, <Pm>.<T>
5552*f5c631daSSadaf Ebrahimi   //  0000 0101 ..10 .... 0100 010. ...0 ....
5553*f5c631daSSadaf Ebrahimi   //  size<23:22> | Pm<19:16> | opc<12:11> = 00 | H<10> = 1 | Pn<8:5> | Pd<3:0>
5554*f5c631daSSadaf Ebrahimi 
5555*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5556*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, pn, pm));
5557*f5c631daSSadaf Ebrahimi 
5558*f5c631daSSadaf Ebrahimi   Emit(ZIP2_p_pp | SVESize(pd) | Pd(pd) | Pn(pn) | Pm(pm));
5559*f5c631daSSadaf Ebrahimi }
5560*f5c631daSSadaf Ebrahimi 
5561*f5c631daSSadaf Ebrahimi // SVEPermuteVectorExtract.
5562*f5c631daSSadaf Ebrahimi 
ext(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm,unsigned offset)5563*f5c631daSSadaf Ebrahimi void Assembler::ext(const ZRegister& zd,
5564*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
5565*f5c631daSSadaf Ebrahimi                     const ZRegister& zm,
5566*f5c631daSSadaf Ebrahimi                     unsigned offset) {
5567*f5c631daSSadaf Ebrahimi   // EXT <Zdn>.B, <Zdn>.B, <Zm>.B, #<imm>
5568*f5c631daSSadaf Ebrahimi   //  0000 0101 001. .... 000. .... .... ....
5569*f5c631daSSadaf Ebrahimi   //  imm8h<20:16> | imm8l<12:10> | Zm<9:5> | Zdn<4:0>
5570*f5c631daSSadaf Ebrahimi 
5571*f5c631daSSadaf Ebrahimi   // EXT <Zd>.B, { <Zn1>.B, <Zn2>.B }, #<imm>
5572*f5c631daSSadaf Ebrahimi   //  0000 0101 011. .... 000. .... .... ....
5573*f5c631daSSadaf Ebrahimi   //  imm8h<20:16> | imm8l<12:10> | Zn<9:5> | Zd<4:0>
5574*f5c631daSSadaf Ebrahimi 
5575*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5576*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(IsUint8(offset));
5577*f5c631daSSadaf Ebrahimi 
5578*f5c631daSSadaf Ebrahimi   int imm8h = ExtractUnsignedBitfield32(7, 3, offset);
5579*f5c631daSSadaf Ebrahimi   int imm8l = ExtractUnsignedBitfield32(2, 0, offset);
5580*f5c631daSSadaf Ebrahimi 
5581*f5c631daSSadaf Ebrahimi   Instr op;
5582*f5c631daSSadaf Ebrahimi   if (zd.Is(zn)) {
5583*f5c631daSSadaf Ebrahimi     // Destructive form.
5584*f5c631daSSadaf Ebrahimi     op = EXT_z_zi_des | Rn(zm);
5585*f5c631daSSadaf Ebrahimi   } else {
5586*f5c631daSSadaf Ebrahimi     // Constructive form (requires SVE2).
5587*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2) && AreConsecutive(zn, zm));
5588*f5c631daSSadaf Ebrahimi     op = 0x05600000 | Rn(zn);
5589*f5c631daSSadaf Ebrahimi   }
5590*f5c631daSSadaf Ebrahimi 
5591*f5c631daSSadaf Ebrahimi   Emit(op | Rd(zd) | ImmUnsignedField<20, 16>(imm8h) |
5592*f5c631daSSadaf Ebrahimi        ImmUnsignedField<12, 10>(imm8l));
5593*f5c631daSSadaf Ebrahimi }
5594*f5c631daSSadaf Ebrahimi 
5595*f5c631daSSadaf Ebrahimi // SVEPermuteVectorInterleaving.
5596*f5c631daSSadaf Ebrahimi 
trn1(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)5597*f5c631daSSadaf Ebrahimi void Assembler::trn1(const ZRegister& zd,
5598*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
5599*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
5600*f5c631daSSadaf Ebrahimi   // TRN1 <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
5601*f5c631daSSadaf Ebrahimi   //  0000 0101 ..1. .... 0111 00.. .... ....
5602*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<12:10> = 100 | Zn<9:5> | Zd<4:0>
5603*f5c631daSSadaf Ebrahimi 
5604*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5605*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
5606*f5c631daSSadaf Ebrahimi 
5607*f5c631daSSadaf Ebrahimi   Emit(TRN1_z_zz | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
5608*f5c631daSSadaf Ebrahimi }
5609*f5c631daSSadaf Ebrahimi 
trn2(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)5610*f5c631daSSadaf Ebrahimi void Assembler::trn2(const ZRegister& zd,
5611*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
5612*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
5613*f5c631daSSadaf Ebrahimi   // TRN2 <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
5614*f5c631daSSadaf Ebrahimi   //  0000 0101 ..1. .... 0111 01.. .... ....
5615*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<12:10> = 101 | Zn<9:5> | Zd<4:0>
5616*f5c631daSSadaf Ebrahimi 
5617*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5618*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
5619*f5c631daSSadaf Ebrahimi 
5620*f5c631daSSadaf Ebrahimi   Emit(TRN2_z_zz | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
5621*f5c631daSSadaf Ebrahimi }
5622*f5c631daSSadaf Ebrahimi 
uzp1(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)5623*f5c631daSSadaf Ebrahimi void Assembler::uzp1(const ZRegister& zd,
5624*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
5625*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
5626*f5c631daSSadaf Ebrahimi   // UZP1 <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
5627*f5c631daSSadaf Ebrahimi   //  0000 0101 ..1. .... 0110 10.. .... ....
5628*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<12:10> = 010 | Zn<9:5> | Zd<4:0>
5629*f5c631daSSadaf Ebrahimi 
5630*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5631*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
5632*f5c631daSSadaf Ebrahimi 
5633*f5c631daSSadaf Ebrahimi   Emit(UZP1_z_zz | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
5634*f5c631daSSadaf Ebrahimi }
5635*f5c631daSSadaf Ebrahimi 
uzp2(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)5636*f5c631daSSadaf Ebrahimi void Assembler::uzp2(const ZRegister& zd,
5637*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
5638*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
5639*f5c631daSSadaf Ebrahimi   // UZP2 <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
5640*f5c631daSSadaf Ebrahimi   //  0000 0101 ..1. .... 0110 11.. .... ....
5641*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<12:10> = 011 | Zn<9:5> | Zd<4:0>
5642*f5c631daSSadaf Ebrahimi 
5643*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5644*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
5645*f5c631daSSadaf Ebrahimi 
5646*f5c631daSSadaf Ebrahimi   Emit(UZP2_z_zz | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
5647*f5c631daSSadaf Ebrahimi }
5648*f5c631daSSadaf Ebrahimi 
zip1(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)5649*f5c631daSSadaf Ebrahimi void Assembler::zip1(const ZRegister& zd,
5650*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
5651*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
5652*f5c631daSSadaf Ebrahimi   // ZIP1 <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
5653*f5c631daSSadaf Ebrahimi   //  0000 0101 ..1. .... 0110 00.. .... ....
5654*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<12:10> = 000 | Zn<9:5> | Zd<4:0>
5655*f5c631daSSadaf Ebrahimi 
5656*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5657*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
5658*f5c631daSSadaf Ebrahimi 
5659*f5c631daSSadaf Ebrahimi   Emit(ZIP1_z_zz | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
5660*f5c631daSSadaf Ebrahimi }
5661*f5c631daSSadaf Ebrahimi 
zip2(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)5662*f5c631daSSadaf Ebrahimi void Assembler::zip2(const ZRegister& zd,
5663*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
5664*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
5665*f5c631daSSadaf Ebrahimi   // ZIP2 <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
5666*f5c631daSSadaf Ebrahimi   //  0000 0101 ..1. .... 0110 01.. .... ....
5667*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<12:10> = 001 | Zn<9:5> | Zd<4:0>
5668*f5c631daSSadaf Ebrahimi 
5669*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5670*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
5671*f5c631daSSadaf Ebrahimi 
5672*f5c631daSSadaf Ebrahimi   Emit(ZIP2_z_zz | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
5673*f5c631daSSadaf Ebrahimi }
5674*f5c631daSSadaf Ebrahimi 
5675*f5c631daSSadaf Ebrahimi // SVEPermuteVectorPredicated.
5676*f5c631daSSadaf Ebrahimi 
clasta(const Register & rd,const PRegister & pg,const Register & rn,const ZRegister & zm)5677*f5c631daSSadaf Ebrahimi void Assembler::clasta(const Register& rd,
5678*f5c631daSSadaf Ebrahimi                        const PRegister& pg,
5679*f5c631daSSadaf Ebrahimi                        const Register& rn,
5680*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
5681*f5c631daSSadaf Ebrahimi   // CLASTA <R><dn>, <Pg>, <R><dn>, <Zm>.<T>
5682*f5c631daSSadaf Ebrahimi   //  0000 0101 ..11 0000 101. .... .... ....
5683*f5c631daSSadaf Ebrahimi   //  size<23:22> | B<16> = 0 | Pg<12:10> | Zm<9:5> | Rdn<4:0>
5684*f5c631daSSadaf Ebrahimi 
5685*f5c631daSSadaf Ebrahimi   USE(rn);
5686*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5687*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(rd.Is(rn));
5688*f5c631daSSadaf Ebrahimi 
5689*f5c631daSSadaf Ebrahimi   Emit(CLASTA_r_p_z | SVESize(zm) | Rd(rd) | PgLow8(pg) | Rn(zm));
5690*f5c631daSSadaf Ebrahimi }
5691*f5c631daSSadaf Ebrahimi 
clasta(const VRegister & vd,const PRegister & pg,const VRegister & vn,const ZRegister & zm)5692*f5c631daSSadaf Ebrahimi void Assembler::clasta(const VRegister& vd,
5693*f5c631daSSadaf Ebrahimi                        const PRegister& pg,
5694*f5c631daSSadaf Ebrahimi                        const VRegister& vn,
5695*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
5696*f5c631daSSadaf Ebrahimi   // CLASTA <V><dn>, <Pg>, <V><dn>, <Zm>.<T>
5697*f5c631daSSadaf Ebrahimi   //  0000 0101 ..10 1010 100. .... .... ....
5698*f5c631daSSadaf Ebrahimi   //  size<23:22> | B<16> = 0 | Pg<12:10> | Zm<9:5> | Vdn<4:0>
5699*f5c631daSSadaf Ebrahimi 
5700*f5c631daSSadaf Ebrahimi   USE(vn);
5701*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5702*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(vd.Is(vn));
5703*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(vd.IsScalar());
5704*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(vd, zm));
5705*f5c631daSSadaf Ebrahimi 
5706*f5c631daSSadaf Ebrahimi   Emit(CLASTA_v_p_z | SVESize(zm) | Rd(vd) | PgLow8(pg) | Rn(zm));
5707*f5c631daSSadaf Ebrahimi }
5708*f5c631daSSadaf Ebrahimi 
clasta(const ZRegister & zd,const PRegister & pg,const ZRegister & zn,const ZRegister & zm)5709*f5c631daSSadaf Ebrahimi void Assembler::clasta(const ZRegister& zd,
5710*f5c631daSSadaf Ebrahimi                        const PRegister& pg,
5711*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
5712*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
5713*f5c631daSSadaf Ebrahimi   // CLASTA <Zdn>.<T>, <Pg>, <Zdn>.<T>, <Zm>.<T>
5714*f5c631daSSadaf Ebrahimi   //  0000 0101 ..10 1000 100. .... .... ....
5715*f5c631daSSadaf Ebrahimi   //  size<23:22> | B<16> = 0 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
5716*f5c631daSSadaf Ebrahimi 
5717*f5c631daSSadaf Ebrahimi   USE(zn);
5718*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5719*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
5720*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
5721*f5c631daSSadaf Ebrahimi 
5722*f5c631daSSadaf Ebrahimi   Emit(CLASTA_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
5723*f5c631daSSadaf Ebrahimi }
5724*f5c631daSSadaf Ebrahimi 
clastb(const Register & rd,const PRegister & pg,const Register & rn,const ZRegister & zm)5725*f5c631daSSadaf Ebrahimi void Assembler::clastb(const Register& rd,
5726*f5c631daSSadaf Ebrahimi                        const PRegister& pg,
5727*f5c631daSSadaf Ebrahimi                        const Register& rn,
5728*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
5729*f5c631daSSadaf Ebrahimi   // CLASTB <R><dn>, <Pg>, <R><dn>, <Zm>.<T>
5730*f5c631daSSadaf Ebrahimi   //  0000 0101 ..11 0001 101. .... .... ....
5731*f5c631daSSadaf Ebrahimi   //  size<23:22> | B<16> = 1 | Pg<12:10> | Zm<9:5> | Rdn<4:0>
5732*f5c631daSSadaf Ebrahimi 
5733*f5c631daSSadaf Ebrahimi   USE(rn);
5734*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5735*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(rd.Is(rn));
5736*f5c631daSSadaf Ebrahimi 
5737*f5c631daSSadaf Ebrahimi   Emit(CLASTB_r_p_z | SVESize(zm) | Rd(rd) | PgLow8(pg) | Rn(zm));
5738*f5c631daSSadaf Ebrahimi }
5739*f5c631daSSadaf Ebrahimi 
clastb(const VRegister & vd,const PRegister & pg,const VRegister & vn,const ZRegister & zm)5740*f5c631daSSadaf Ebrahimi void Assembler::clastb(const VRegister& vd,
5741*f5c631daSSadaf Ebrahimi                        const PRegister& pg,
5742*f5c631daSSadaf Ebrahimi                        const VRegister& vn,
5743*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
5744*f5c631daSSadaf Ebrahimi   // CLASTB <V><dn>, <Pg>, <V><dn>, <Zm>.<T>
5745*f5c631daSSadaf Ebrahimi   //  0000 0101 ..10 1011 100. .... .... ....
5746*f5c631daSSadaf Ebrahimi   //  size<23:22> | B<16> = 1 | Pg<12:10> | Zm<9:5> | Vdn<4:0>
5747*f5c631daSSadaf Ebrahimi 
5748*f5c631daSSadaf Ebrahimi   USE(vn);
5749*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5750*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(vd.Is(vn));
5751*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(vd.IsScalar());
5752*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(vd, zm));
5753*f5c631daSSadaf Ebrahimi 
5754*f5c631daSSadaf Ebrahimi   Emit(CLASTB_v_p_z | SVESize(zm) | Rd(vd) | PgLow8(pg) | Rn(zm));
5755*f5c631daSSadaf Ebrahimi }
5756*f5c631daSSadaf Ebrahimi 
clastb(const ZRegister & zd,const PRegister & pg,const ZRegister & zn,const ZRegister & zm)5757*f5c631daSSadaf Ebrahimi void Assembler::clastb(const ZRegister& zd,
5758*f5c631daSSadaf Ebrahimi                        const PRegister& pg,
5759*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
5760*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
5761*f5c631daSSadaf Ebrahimi   // CLASTB <Zdn>.<T>, <Pg>, <Zdn>.<T>, <Zm>.<T>
5762*f5c631daSSadaf Ebrahimi   //  0000 0101 ..10 1001 100. .... .... ....
5763*f5c631daSSadaf Ebrahimi   //  size<23:22> | B<16> = 1 | Pg<12:10> | Zm<9:5> | Zdn<4:0>
5764*f5c631daSSadaf Ebrahimi 
5765*f5c631daSSadaf Ebrahimi   USE(zn);
5766*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5767*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
5768*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
5769*f5c631daSSadaf Ebrahimi 
5770*f5c631daSSadaf Ebrahimi   Emit(CLASTB_z_p_zz | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
5771*f5c631daSSadaf Ebrahimi }
5772*f5c631daSSadaf Ebrahimi 
compact(const ZRegister & zd,const PRegister & pg,const ZRegister & zn)5773*f5c631daSSadaf Ebrahimi void Assembler::compact(const ZRegister& zd,
5774*f5c631daSSadaf Ebrahimi                         const PRegister& pg,
5775*f5c631daSSadaf Ebrahimi                         const ZRegister& zn) {
5776*f5c631daSSadaf Ebrahimi   // COMPACT <Zd>.<T>, <Pg>, <Zn>.<T>
5777*f5c631daSSadaf Ebrahimi   //  0000 0101 1.10 0001 100. .... .... ....
5778*f5c631daSSadaf Ebrahimi   //  sz<22> | Pg<12:10> | Zn<9:5> | Zd<4:0>
5779*f5c631daSSadaf Ebrahimi 
5780*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5781*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
5782*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((zd.GetLaneSizeInBits() == kSRegSize) ||
5783*f5c631daSSadaf Ebrahimi               (zd.GetLaneSizeInBits() == kDRegSize));
5784*f5c631daSSadaf Ebrahimi 
5785*f5c631daSSadaf Ebrahimi   Instr sz = (zd.GetLaneSizeInBits() == kDRegSize) ? (1 << 22) : 0;
5786*f5c631daSSadaf Ebrahimi   Emit(COMPACT_z_p_z | sz | Rd(zd) | PgLow8(pg) | Rn(zn));
5787*f5c631daSSadaf Ebrahimi }
5788*f5c631daSSadaf Ebrahimi 
cpy(const ZRegister & zd,const PRegisterM & pg,const Register & rn)5789*f5c631daSSadaf Ebrahimi void Assembler::cpy(const ZRegister& zd,
5790*f5c631daSSadaf Ebrahimi                     const PRegisterM& pg,
5791*f5c631daSSadaf Ebrahimi                     const Register& rn) {
5792*f5c631daSSadaf Ebrahimi   // CPY <Zd>.<T>, <Pg>/M, <R><n|SP>
5793*f5c631daSSadaf Ebrahimi   //  0000 0101 ..10 1000 101. .... .... ....
5794*f5c631daSSadaf Ebrahimi   //  size<23:22> | Pg<12:10> | Rn<9:5> | Zd<4:0>
5795*f5c631daSSadaf Ebrahimi 
5796*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5797*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(static_cast<unsigned>(rn.GetSizeInBits()) >=
5798*f5c631daSSadaf Ebrahimi               zd.GetLaneSizeInBits());
5799*f5c631daSSadaf Ebrahimi 
5800*f5c631daSSadaf Ebrahimi   Emit(CPY_z_p_r | SVESize(zd) | Rd(zd) | PgLow8(pg) | RnSP(rn));
5801*f5c631daSSadaf Ebrahimi }
5802*f5c631daSSadaf Ebrahimi 
cpy(const ZRegister & zd,const PRegisterM & pg,const VRegister & vn)5803*f5c631daSSadaf Ebrahimi void Assembler::cpy(const ZRegister& zd,
5804*f5c631daSSadaf Ebrahimi                     const PRegisterM& pg,
5805*f5c631daSSadaf Ebrahimi                     const VRegister& vn) {
5806*f5c631daSSadaf Ebrahimi   // CPY <Zd>.<T>, <Pg>/M, <V><n>
5807*f5c631daSSadaf Ebrahimi   //  0000 0101 ..10 0000 100. .... .... ....
5808*f5c631daSSadaf Ebrahimi   //  size<23:22> | Pg<12:10> | Vn<9:5> | Zd<4:0>
5809*f5c631daSSadaf Ebrahimi 
5810*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5811*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(vn.IsScalar());
5812*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(static_cast<unsigned>(vn.GetSizeInBits()) ==
5813*f5c631daSSadaf Ebrahimi               zd.GetLaneSizeInBits());
5814*f5c631daSSadaf Ebrahimi 
5815*f5c631daSSadaf Ebrahimi   Emit(CPY_z_p_v | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(vn));
5816*f5c631daSSadaf Ebrahimi }
5817*f5c631daSSadaf Ebrahimi 
lasta(const Register & rd,const PRegister & pg,const ZRegister & zn)5818*f5c631daSSadaf Ebrahimi void Assembler::lasta(const Register& rd,
5819*f5c631daSSadaf Ebrahimi                       const PRegister& pg,
5820*f5c631daSSadaf Ebrahimi                       const ZRegister& zn) {
5821*f5c631daSSadaf Ebrahimi   // LASTA <R><d>, <Pg>, <Zn>.<T>
5822*f5c631daSSadaf Ebrahimi   //  0000 0101 ..10 0000 101. .... .... ....
5823*f5c631daSSadaf Ebrahimi   //  size<23:22> | B<16> = 0 | Pg<12:10> | Zn<9:5> | Rd<4:0>
5824*f5c631daSSadaf Ebrahimi 
5825*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5826*f5c631daSSadaf Ebrahimi 
5827*f5c631daSSadaf Ebrahimi   Emit(LASTA_r_p_z | SVESize(zn) | Rd(rd) | PgLow8(pg) | Rn(zn));
5828*f5c631daSSadaf Ebrahimi }
5829*f5c631daSSadaf Ebrahimi 
lasta(const VRegister & vd,const PRegister & pg,const ZRegister & zn)5830*f5c631daSSadaf Ebrahimi void Assembler::lasta(const VRegister& vd,
5831*f5c631daSSadaf Ebrahimi                       const PRegister& pg,
5832*f5c631daSSadaf Ebrahimi                       const ZRegister& zn) {
5833*f5c631daSSadaf Ebrahimi   // LASTA <V><d>, <Pg>, <Zn>.<T>
5834*f5c631daSSadaf Ebrahimi   //  0000 0101 ..10 0010 100. .... .... ....
5835*f5c631daSSadaf Ebrahimi   //  size<23:22> | B<16> = 0 | Pg<12:10> | Zn<9:5> | Vd<4:0>
5836*f5c631daSSadaf Ebrahimi 
5837*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5838*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(vd.IsScalar());
5839*f5c631daSSadaf Ebrahimi 
5840*f5c631daSSadaf Ebrahimi   Emit(LASTA_v_p_z | SVESize(zn) | Rd(vd) | PgLow8(pg) | Rn(zn));
5841*f5c631daSSadaf Ebrahimi }
5842*f5c631daSSadaf Ebrahimi 
lastb(const Register & rd,const PRegister & pg,const ZRegister & zn)5843*f5c631daSSadaf Ebrahimi void Assembler::lastb(const Register& rd,
5844*f5c631daSSadaf Ebrahimi                       const PRegister& pg,
5845*f5c631daSSadaf Ebrahimi                       const ZRegister& zn) {
5846*f5c631daSSadaf Ebrahimi   // LASTB <R><d>, <Pg>, <Zn>.<T>
5847*f5c631daSSadaf Ebrahimi   //  0000 0101 ..10 0001 101. .... .... ....
5848*f5c631daSSadaf Ebrahimi   //  size<23:22> | B<16> = 1 | Pg<12:10> | Zn<9:5> | Rd<4:0>
5849*f5c631daSSadaf Ebrahimi 
5850*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5851*f5c631daSSadaf Ebrahimi 
5852*f5c631daSSadaf Ebrahimi   Emit(LASTB_r_p_z | SVESize(zn) | Rd(rd) | PgLow8(pg) | Rn(zn));
5853*f5c631daSSadaf Ebrahimi }
5854*f5c631daSSadaf Ebrahimi 
lastb(const VRegister & vd,const PRegister & pg,const ZRegister & zn)5855*f5c631daSSadaf Ebrahimi void Assembler::lastb(const VRegister& vd,
5856*f5c631daSSadaf Ebrahimi                       const PRegister& pg,
5857*f5c631daSSadaf Ebrahimi                       const ZRegister& zn) {
5858*f5c631daSSadaf Ebrahimi   // LASTB <V><d>, <Pg>, <Zn>.<T>
5859*f5c631daSSadaf Ebrahimi   //  0000 0101 ..10 0011 100. .... .... ....
5860*f5c631daSSadaf Ebrahimi   //  size<23:22> | B<16> = 1 | Pg<12:10> | Zn<9:5> | Vd<4:0>
5861*f5c631daSSadaf Ebrahimi 
5862*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5863*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(vd.IsScalar());
5864*f5c631daSSadaf Ebrahimi 
5865*f5c631daSSadaf Ebrahimi   Emit(LASTB_v_p_z | SVESize(zn) | Rd(vd) | PgLow8(pg) | Rn(zn));
5866*f5c631daSSadaf Ebrahimi }
5867*f5c631daSSadaf Ebrahimi 
rbit(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)5868*f5c631daSSadaf Ebrahimi void Assembler::rbit(const ZRegister& zd,
5869*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
5870*f5c631daSSadaf Ebrahimi                      const ZRegister& zn) {
5871*f5c631daSSadaf Ebrahimi   // RBIT <Zd>.<T>, <Pg>/M, <Zn>.<T>
5872*f5c631daSSadaf Ebrahimi   //  0000 0101 ..10 0111 100. .... .... ....
5873*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<17:16> = 11 | Pg<12:10> | Zn<9:5> | Zd<4:0>
5874*f5c631daSSadaf Ebrahimi 
5875*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5876*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
5877*f5c631daSSadaf Ebrahimi 
5878*f5c631daSSadaf Ebrahimi   Emit(RBIT_z_p_z | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
5879*f5c631daSSadaf Ebrahimi }
5880*f5c631daSSadaf Ebrahimi 
revb(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)5881*f5c631daSSadaf Ebrahimi void Assembler::revb(const ZRegister& zd,
5882*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
5883*f5c631daSSadaf Ebrahimi                      const ZRegister& zn) {
5884*f5c631daSSadaf Ebrahimi   // REVB <Zd>.<T>, <Pg>/M, <Zn>.<T>
5885*f5c631daSSadaf Ebrahimi   //  0000 0101 ..10 0100 100. .... .... ....
5886*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<17:16> = 00 | Pg<12:10> | Zn<9:5> | Zd<4:0>
5887*f5c631daSSadaf Ebrahimi 
5888*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5889*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
5890*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeH() || zd.IsLaneSizeS() || zd.IsLaneSizeD());
5891*f5c631daSSadaf Ebrahimi 
5892*f5c631daSSadaf Ebrahimi   Emit(REVB_z_z | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
5893*f5c631daSSadaf Ebrahimi }
5894*f5c631daSSadaf Ebrahimi 
revh(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)5895*f5c631daSSadaf Ebrahimi void Assembler::revh(const ZRegister& zd,
5896*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
5897*f5c631daSSadaf Ebrahimi                      const ZRegister& zn) {
5898*f5c631daSSadaf Ebrahimi   // REVH <Zd>.<T>, <Pg>/M, <Zn>.<T>
5899*f5c631daSSadaf Ebrahimi   //  0000 0101 ..10 0101 100. .... .... ....
5900*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<17:16> = 01 | Pg<12:10> | Zn<9:5> | Zd<4:0>
5901*f5c631daSSadaf Ebrahimi 
5902*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5903*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
5904*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeS() || zd.IsLaneSizeD());
5905*f5c631daSSadaf Ebrahimi 
5906*f5c631daSSadaf Ebrahimi   Emit(REVH_z_z | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
5907*f5c631daSSadaf Ebrahimi }
5908*f5c631daSSadaf Ebrahimi 
revw(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)5909*f5c631daSSadaf Ebrahimi void Assembler::revw(const ZRegister& zd,
5910*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
5911*f5c631daSSadaf Ebrahimi                      const ZRegister& zn) {
5912*f5c631daSSadaf Ebrahimi   // REVW <Zd>.D, <Pg>/M, <Zn>.D
5913*f5c631daSSadaf Ebrahimi   //  0000 0101 ..10 0110 100. .... .... ....
5914*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<17:16> = 10 | Pg<12:10> | Zn<9:5> | Zd<4:0>
5915*f5c631daSSadaf Ebrahimi 
5916*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5917*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
5918*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeD());
5919*f5c631daSSadaf Ebrahimi 
5920*f5c631daSSadaf Ebrahimi   Emit(REVW_z_z | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
5921*f5c631daSSadaf Ebrahimi }
5922*f5c631daSSadaf Ebrahimi 
splice(const ZRegister & zd,const PRegister & pg,const ZRegister & zn,const ZRegister & zm)5923*f5c631daSSadaf Ebrahimi void Assembler::splice(const ZRegister& zd,
5924*f5c631daSSadaf Ebrahimi                        const PRegister& pg,
5925*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
5926*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
5927*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
5928*f5c631daSSadaf Ebrahimi 
5929*f5c631daSSadaf Ebrahimi   if (zd.Aliases(zn)) {
5930*f5c631daSSadaf Ebrahimi     // SPLICE <Zdn>.<T>, <Pg>, <Zdn>.<T>, <Zm>.<T>
5931*f5c631daSSadaf Ebrahimi     //  0000 0101 ..10 1100 100. .... .... ....
5932*f5c631daSSadaf Ebrahimi     //  size<23:22> | Pg<12:10> | Zm<9:5> | Zdn<4:0>
5933*f5c631daSSadaf Ebrahimi 
5934*f5c631daSSadaf Ebrahimi     USE(zn);
5935*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5936*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zd.Is(zn));
5937*f5c631daSSadaf Ebrahimi 
5938*f5c631daSSadaf Ebrahimi     Emit(SPLICE_z_p_zz_des | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
5939*f5c631daSSadaf Ebrahimi   } else {
5940*f5c631daSSadaf Ebrahimi     splice_con(zd, pg, zn, zm);
5941*f5c631daSSadaf Ebrahimi   }
5942*f5c631daSSadaf Ebrahimi }
5943*f5c631daSSadaf Ebrahimi 
splice_con(const ZRegister & zd,const PRegister & pg,const ZRegister & zn1,const ZRegister & zn2)5944*f5c631daSSadaf Ebrahimi void Assembler::splice_con(const ZRegister& zd,
5945*f5c631daSSadaf Ebrahimi                            const PRegister& pg,
5946*f5c631daSSadaf Ebrahimi                            const ZRegister& zn1,
5947*f5c631daSSadaf Ebrahimi                            const ZRegister& zn2) {
5948*f5c631daSSadaf Ebrahimi   // SPLICE <Zd>.<T>, <Pg>, { <Zn1>.<T>, <Zn2>.<T> }
5949*f5c631daSSadaf Ebrahimi   //  0000 0101 ..10 1101 100. .... .... ....
5950*f5c631daSSadaf Ebrahimi   //  size<23:22> | Pg<12:10> | Zn<9:5> | Zd<4:0>
5951*f5c631daSSadaf Ebrahimi 
5952*f5c631daSSadaf Ebrahimi   USE(zn2);
5953*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
5954*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreConsecutive(zn1, zn2));
5955*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn1, zn2));
5956*f5c631daSSadaf Ebrahimi 
5957*f5c631daSSadaf Ebrahimi   Emit(0x052d8000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn1));
5958*f5c631daSSadaf Ebrahimi }
5959*f5c631daSSadaf Ebrahimi 
5960*f5c631daSSadaf Ebrahimi // SVEPermuteVectorUnpredicated.
5961*f5c631daSSadaf Ebrahimi 
dup(const ZRegister & zd,const Register & xn)5962*f5c631daSSadaf Ebrahimi void Assembler::dup(const ZRegister& zd, const Register& xn) {
5963*f5c631daSSadaf Ebrahimi   // DUP <Zd>.<T>, <R><n|SP>
5964*f5c631daSSadaf Ebrahimi   //  0000 0101 ..10 0000 0011 10.. .... ....
5965*f5c631daSSadaf Ebrahimi   //  size<23:22> | Rn<9:5> | Zd<4:0>
5966*f5c631daSSadaf Ebrahimi 
5967*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5968*f5c631daSSadaf Ebrahimi 
5969*f5c631daSSadaf Ebrahimi   Emit(DUP_z_r | SVESize(zd) | Rd(zd) | RnSP(xn));
5970*f5c631daSSadaf Ebrahimi }
5971*f5c631daSSadaf Ebrahimi 
dup(const ZRegister & zd,const ZRegister & zn,unsigned index)5972*f5c631daSSadaf Ebrahimi void Assembler::dup(const ZRegister& zd, const ZRegister& zn, unsigned index) {
5973*f5c631daSSadaf Ebrahimi   // DUP <Zd>.<T>, <Zn>.<T>[<imm>]
5974*f5c631daSSadaf Ebrahimi   //  0000 0101 ..1. .... 0010 00.. .... ....
5975*f5c631daSSadaf Ebrahimi   //  imm2<23:22> | tsz<20:16> | Zn<9:5> | Zd<4:0>
5976*f5c631daSSadaf Ebrahimi 
5977*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5978*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(zd, zn));
5979*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((index * zd.GetLaneSizeInBits()) < 512);
5980*f5c631daSSadaf Ebrahimi   int n = zd.GetLaneSizeInBytesLog2();
5981*f5c631daSSadaf Ebrahimi   unsigned imm_7 = (index << (n + 1)) | (1 << n);
5982*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(IsUint7(imm_7));
5983*f5c631daSSadaf Ebrahimi   unsigned imm_2 = ExtractUnsignedBitfield32(6, 5, imm_7);
5984*f5c631daSSadaf Ebrahimi   unsigned tsz_5 = ExtractUnsignedBitfield32(4, 0, imm_7);
5985*f5c631daSSadaf Ebrahimi 
5986*f5c631daSSadaf Ebrahimi   Emit(DUP_z_zi | ImmUnsignedField<23, 22>(imm_2) |
5987*f5c631daSSadaf Ebrahimi        ImmUnsignedField<20, 16>(tsz_5) | Rd(zd) | Rn(zn));
5988*f5c631daSSadaf Ebrahimi }
5989*f5c631daSSadaf Ebrahimi 
insr(const ZRegister & zdn,const Register & rm)5990*f5c631daSSadaf Ebrahimi void Assembler::insr(const ZRegister& zdn, const Register& rm) {
5991*f5c631daSSadaf Ebrahimi   // INSR <Zdn>.<T>, <R><m>
5992*f5c631daSSadaf Ebrahimi   //  0000 0101 ..10 0100 0011 10.. .... ....
5993*f5c631daSSadaf Ebrahimi   //  size<23:22> | Rm<9:5> | Zdn<4:0>
5994*f5c631daSSadaf Ebrahimi 
5995*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
5996*f5c631daSSadaf Ebrahimi 
5997*f5c631daSSadaf Ebrahimi   Emit(INSR_z_r | SVESize(zdn) | Rd(zdn) | Rn(rm));
5998*f5c631daSSadaf Ebrahimi }
5999*f5c631daSSadaf Ebrahimi 
insr(const ZRegister & zdn,const VRegister & vm)6000*f5c631daSSadaf Ebrahimi void Assembler::insr(const ZRegister& zdn, const VRegister& vm) {
6001*f5c631daSSadaf Ebrahimi   // INSR <Zdn>.<T>, <V><m>
6002*f5c631daSSadaf Ebrahimi   //  0000 0101 ..11 0100 0011 10.. .... ....
6003*f5c631daSSadaf Ebrahimi   //  size<23:22> | Vm<9:5> | Zdn<4:0>
6004*f5c631daSSadaf Ebrahimi 
6005*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6006*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(vm.IsScalar());
6007*f5c631daSSadaf Ebrahimi 
6008*f5c631daSSadaf Ebrahimi   Emit(INSR_z_v | SVESize(zdn) | Rd(zdn) | Rn(vm));
6009*f5c631daSSadaf Ebrahimi }
6010*f5c631daSSadaf Ebrahimi 
rev(const ZRegister & zd,const ZRegister & zn)6011*f5c631daSSadaf Ebrahimi void Assembler::rev(const ZRegister& zd, const ZRegister& zn) {
6012*f5c631daSSadaf Ebrahimi   // REV <Zd>.<T>, <Zn>.<T>
6013*f5c631daSSadaf Ebrahimi   //  0000 0101 ..11 1000 0011 10.. .... ....
6014*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zn<9:5> | Zd<4:0>
6015*f5c631daSSadaf Ebrahimi 
6016*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6017*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(zd, zn));
6018*f5c631daSSadaf Ebrahimi 
6019*f5c631daSSadaf Ebrahimi   Emit(REV_z_z | SVESize(zd) | Rd(zd) | Rn(zn));
6020*f5c631daSSadaf Ebrahimi }
6021*f5c631daSSadaf Ebrahimi 
sunpkhi(const ZRegister & zd,const ZRegister & zn)6022*f5c631daSSadaf Ebrahimi void Assembler::sunpkhi(const ZRegister& zd, const ZRegister& zn) {
6023*f5c631daSSadaf Ebrahimi   // SUNPKHI <Zd>.<T>, <Zn>.<Tb>
6024*f5c631daSSadaf Ebrahimi   //  0000 0101 ..11 0001 0011 10.. .... ....
6025*f5c631daSSadaf Ebrahimi   //  size<23:22> | U<17> = 0 | H<16> = 1 | Zn<9:5> | Zd<4:0>
6026*f5c631daSSadaf Ebrahimi 
6027*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6028*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
6029*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zd.IsLaneSizeB());
6030*f5c631daSSadaf Ebrahimi 
6031*f5c631daSSadaf Ebrahimi   Emit(SUNPKHI_z_z | SVESize(zd) | Rd(zd) | Rn(zn));
6032*f5c631daSSadaf Ebrahimi }
6033*f5c631daSSadaf Ebrahimi 
sunpklo(const ZRegister & zd,const ZRegister & zn)6034*f5c631daSSadaf Ebrahimi void Assembler::sunpklo(const ZRegister& zd, const ZRegister& zn) {
6035*f5c631daSSadaf Ebrahimi   // SUNPKLO <Zd>.<T>, <Zn>.<Tb>
6036*f5c631daSSadaf Ebrahimi   //  0000 0101 ..11 0000 0011 10.. .... ....
6037*f5c631daSSadaf Ebrahimi   //  size<23:22> | U<17> = 0 | H<16> = 0 | Zn<9:5> | Zd<4:0>
6038*f5c631daSSadaf Ebrahimi 
6039*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6040*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
6041*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zd.IsLaneSizeB());
6042*f5c631daSSadaf Ebrahimi 
6043*f5c631daSSadaf Ebrahimi   Emit(SUNPKLO_z_z | SVESize(zd) | Rd(zd) | Rn(zn));
6044*f5c631daSSadaf Ebrahimi }
6045*f5c631daSSadaf Ebrahimi 
tbl(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6046*f5c631daSSadaf Ebrahimi void Assembler::tbl(const ZRegister& zd,
6047*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
6048*f5c631daSSadaf Ebrahimi                     const ZRegister& zm) {
6049*f5c631daSSadaf Ebrahimi   // TBL <Zd>.<T>, { <Zn>.<T> }, <Zm>.<T>
6050*f5c631daSSadaf Ebrahimi   //  0000 0101 ..1. .... 0011 00.. .... ....
6051*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | Zn<9:5> | Zd<4:0>
6052*f5c631daSSadaf Ebrahimi 
6053*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6054*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(zd, zn, zm));
6055*f5c631daSSadaf Ebrahimi 
6056*f5c631daSSadaf Ebrahimi   Emit(TBL_z_zz_1 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
6057*f5c631daSSadaf Ebrahimi }
6058*f5c631daSSadaf Ebrahimi 
uunpkhi(const ZRegister & zd,const ZRegister & zn)6059*f5c631daSSadaf Ebrahimi void Assembler::uunpkhi(const ZRegister& zd, const ZRegister& zn) {
6060*f5c631daSSadaf Ebrahimi   // UUNPKHI <Zd>.<T>, <Zn>.<Tb>
6061*f5c631daSSadaf Ebrahimi   //  0000 0101 ..11 0011 0011 10.. .... ....
6062*f5c631daSSadaf Ebrahimi   //  size<23:22> | U<17> = 1 | H<16> = 1 | Zn<9:5> | Zd<4:0>
6063*f5c631daSSadaf Ebrahimi 
6064*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6065*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
6066*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zd.IsLaneSizeB());
6067*f5c631daSSadaf Ebrahimi 
6068*f5c631daSSadaf Ebrahimi   Emit(UUNPKHI_z_z | SVESize(zd) | Rd(zd) | Rn(zn));
6069*f5c631daSSadaf Ebrahimi }
6070*f5c631daSSadaf Ebrahimi 
uunpklo(const ZRegister & zd,const ZRegister & zn)6071*f5c631daSSadaf Ebrahimi void Assembler::uunpklo(const ZRegister& zd, const ZRegister& zn) {
6072*f5c631daSSadaf Ebrahimi   // UUNPKLO <Zd>.<T>, <Zn>.<Tb>
6073*f5c631daSSadaf Ebrahimi   //  0000 0101 ..11 0010 0011 10.. .... ....
6074*f5c631daSSadaf Ebrahimi   //  size<23:22> | U<17> = 1 | H<16> = 0 | Zn<9:5> | Zd<4:0>
6075*f5c631daSSadaf Ebrahimi 
6076*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6077*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
6078*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zd.IsLaneSizeB());
6079*f5c631daSSadaf Ebrahimi 
6080*f5c631daSSadaf Ebrahimi   Emit(UUNPKLO_z_z | SVESize(zd) | Rd(zd) | Rn(zn));
6081*f5c631daSSadaf Ebrahimi }
6082*f5c631daSSadaf Ebrahimi 
6083*f5c631daSSadaf Ebrahimi // SVEPredicateCount.
6084*f5c631daSSadaf Ebrahimi 
cntp(const Register & xd,const PRegister & pg,const PRegisterWithLaneSize & pn)6085*f5c631daSSadaf Ebrahimi void Assembler::cntp(const Register& xd,
6086*f5c631daSSadaf Ebrahimi                      const PRegister& pg,
6087*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pn) {
6088*f5c631daSSadaf Ebrahimi   // CNTP <Xd>, <Pg>, <Pn>.<T>
6089*f5c631daSSadaf Ebrahimi   //  0010 0101 ..10 0000 10.. ..0. .... ....
6090*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> = 000 | Pg<13:10> | o2<9> = 0 | Pn<8:5> | Rd<4:0>
6091*f5c631daSSadaf Ebrahimi 
6092*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6093*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(xd.IsX());
6094*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pg.IsUnqualified());
6095*f5c631daSSadaf Ebrahimi   if (pg.HasLaneSize()) VIXL_ASSERT(AreSameFormat(pg, pn));
6096*f5c631daSSadaf Ebrahimi 
6097*f5c631daSSadaf Ebrahimi   Emit(CNTP_r_p_p | SVESize(pn) | Rd(xd) | Pg<13, 10>(pg) | Pn(pn));
6098*f5c631daSSadaf Ebrahimi }
6099*f5c631daSSadaf Ebrahimi 
6100*f5c631daSSadaf Ebrahimi // SVEPredicateLogicalOp.
and_(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)6101*f5c631daSSadaf Ebrahimi void Assembler::and_(const PRegisterWithLaneSize& pd,
6102*f5c631daSSadaf Ebrahimi                      const PRegisterZ& pg,
6103*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pn,
6104*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pm) {
6105*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6106*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(pd, pn, pm));
6107*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pd.IsLaneSizeB());
6108*f5c631daSSadaf Ebrahimi   Emit(AND_p_p_pp_z | Pd(pd) | Pg<13, 10>(pg) | Pn(pn) | Pm(pm));
6109*f5c631daSSadaf Ebrahimi }
6110*f5c631daSSadaf Ebrahimi 
ands(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)6111*f5c631daSSadaf Ebrahimi void Assembler::ands(const PRegisterWithLaneSize& pd,
6112*f5c631daSSadaf Ebrahimi                      const PRegisterZ& pg,
6113*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pn,
6114*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pm) {
6115*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6116*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(pd, pn, pm));
6117*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pd.IsLaneSizeB());
6118*f5c631daSSadaf Ebrahimi   Emit(ANDS_p_p_pp_z | Pd(pd) | Pg<13, 10>(pg) | Pn(pn) | Pm(pm));
6119*f5c631daSSadaf Ebrahimi }
6120*f5c631daSSadaf Ebrahimi 
bic(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)6121*f5c631daSSadaf Ebrahimi void Assembler::bic(const PRegisterWithLaneSize& pd,
6122*f5c631daSSadaf Ebrahimi                     const PRegisterZ& pg,
6123*f5c631daSSadaf Ebrahimi                     const PRegisterWithLaneSize& pn,
6124*f5c631daSSadaf Ebrahimi                     const PRegisterWithLaneSize& pm) {
6125*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6126*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(pd, pn, pm));
6127*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pd.IsLaneSizeB());
6128*f5c631daSSadaf Ebrahimi   Emit(BIC_p_p_pp_z | Pd(pd) | Pg<13, 10>(pg) | Pn(pn) | Pm(pm));
6129*f5c631daSSadaf Ebrahimi }
6130*f5c631daSSadaf Ebrahimi 
bics(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)6131*f5c631daSSadaf Ebrahimi void Assembler::bics(const PRegisterWithLaneSize& pd,
6132*f5c631daSSadaf Ebrahimi                      const PRegisterZ& pg,
6133*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pn,
6134*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pm) {
6135*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6136*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(pd, pn, pm));
6137*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pd.IsLaneSizeB());
6138*f5c631daSSadaf Ebrahimi   Emit(BICS_p_p_pp_z | Pd(pd) | Pg<13, 10>(pg) | Pn(pn) | Pm(pm));
6139*f5c631daSSadaf Ebrahimi }
6140*f5c631daSSadaf Ebrahimi 
eor(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)6141*f5c631daSSadaf Ebrahimi void Assembler::eor(const PRegisterWithLaneSize& pd,
6142*f5c631daSSadaf Ebrahimi                     const PRegisterZ& pg,
6143*f5c631daSSadaf Ebrahimi                     const PRegisterWithLaneSize& pn,
6144*f5c631daSSadaf Ebrahimi                     const PRegisterWithLaneSize& pm) {
6145*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6146*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(pd, pn, pm));
6147*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pd.IsLaneSizeB());
6148*f5c631daSSadaf Ebrahimi   Emit(EOR_p_p_pp_z | Pd(pd) | Pg<13, 10>(pg) | Pn(pn) | Pm(pm));
6149*f5c631daSSadaf Ebrahimi }
6150*f5c631daSSadaf Ebrahimi 
eors(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)6151*f5c631daSSadaf Ebrahimi void Assembler::eors(const PRegisterWithLaneSize& pd,
6152*f5c631daSSadaf Ebrahimi                      const PRegisterZ& pg,
6153*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pn,
6154*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pm) {
6155*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6156*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(pd, pn, pm));
6157*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pd.IsLaneSizeB());
6158*f5c631daSSadaf Ebrahimi   Emit(EORS_p_p_pp_z | Pd(pd) | Pg<13, 10>(pg) | Pn(pn) | Pm(pm));
6159*f5c631daSSadaf Ebrahimi }
6160*f5c631daSSadaf Ebrahimi 
nand(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)6161*f5c631daSSadaf Ebrahimi void Assembler::nand(const PRegisterWithLaneSize& pd,
6162*f5c631daSSadaf Ebrahimi                      const PRegisterZ& pg,
6163*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pn,
6164*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pm) {
6165*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6166*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(pd, pn, pm));
6167*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pd.IsLaneSizeB());
6168*f5c631daSSadaf Ebrahimi   Emit(NAND_p_p_pp_z | Pd(pd) | Pg<13, 10>(pg) | Pn(pn) | Pm(pm));
6169*f5c631daSSadaf Ebrahimi }
6170*f5c631daSSadaf Ebrahimi 
nands(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)6171*f5c631daSSadaf Ebrahimi void Assembler::nands(const PRegisterWithLaneSize& pd,
6172*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
6173*f5c631daSSadaf Ebrahimi                       const PRegisterWithLaneSize& pn,
6174*f5c631daSSadaf Ebrahimi                       const PRegisterWithLaneSize& pm) {
6175*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6176*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(pd, pn, pm));
6177*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pd.IsLaneSizeB());
6178*f5c631daSSadaf Ebrahimi   Emit(NANDS_p_p_pp_z | Pd(pd) | Pg<13, 10>(pg) | Pn(pn) | Pm(pm));
6179*f5c631daSSadaf Ebrahimi }
6180*f5c631daSSadaf Ebrahimi 
nor(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)6181*f5c631daSSadaf Ebrahimi void Assembler::nor(const PRegisterWithLaneSize& pd,
6182*f5c631daSSadaf Ebrahimi                     const PRegisterZ& pg,
6183*f5c631daSSadaf Ebrahimi                     const PRegisterWithLaneSize& pn,
6184*f5c631daSSadaf Ebrahimi                     const PRegisterWithLaneSize& pm) {
6185*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6186*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(pd, pn, pm));
6187*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pd.IsLaneSizeB());
6188*f5c631daSSadaf Ebrahimi   Emit(NOR_p_p_pp_z | Pd(pd) | Pg<13, 10>(pg) | Pn(pn) | Pm(pm));
6189*f5c631daSSadaf Ebrahimi }
6190*f5c631daSSadaf Ebrahimi 
nors(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)6191*f5c631daSSadaf Ebrahimi void Assembler::nors(const PRegisterWithLaneSize& pd,
6192*f5c631daSSadaf Ebrahimi                      const PRegisterZ& pg,
6193*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pn,
6194*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pm) {
6195*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6196*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(pd, pn, pm));
6197*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pd.IsLaneSizeB());
6198*f5c631daSSadaf Ebrahimi   Emit(NORS_p_p_pp_z | Pd(pd) | Pg<13, 10>(pg) | Pn(pn) | Pm(pm));
6199*f5c631daSSadaf Ebrahimi }
6200*f5c631daSSadaf Ebrahimi 
orn(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)6201*f5c631daSSadaf Ebrahimi void Assembler::orn(const PRegisterWithLaneSize& pd,
6202*f5c631daSSadaf Ebrahimi                     const PRegisterZ& pg,
6203*f5c631daSSadaf Ebrahimi                     const PRegisterWithLaneSize& pn,
6204*f5c631daSSadaf Ebrahimi                     const PRegisterWithLaneSize& pm) {
6205*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6206*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(pd, pn, pm));
6207*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pd.IsLaneSizeB());
6208*f5c631daSSadaf Ebrahimi   Emit(ORN_p_p_pp_z | Pd(pd) | Pg<13, 10>(pg) | Pn(pn) | Pm(pm));
6209*f5c631daSSadaf Ebrahimi }
6210*f5c631daSSadaf Ebrahimi 
orns(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)6211*f5c631daSSadaf Ebrahimi void Assembler::orns(const PRegisterWithLaneSize& pd,
6212*f5c631daSSadaf Ebrahimi                      const PRegisterZ& pg,
6213*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pn,
6214*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pm) {
6215*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6216*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(pd, pn, pm));
6217*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pd.IsLaneSizeB());
6218*f5c631daSSadaf Ebrahimi   Emit(ORNS_p_p_pp_z | Pd(pd) | Pg<13, 10>(pg) | Pn(pn) | Pm(pm));
6219*f5c631daSSadaf Ebrahimi }
6220*f5c631daSSadaf Ebrahimi 
orr(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)6221*f5c631daSSadaf Ebrahimi void Assembler::orr(const PRegisterWithLaneSize& pd,
6222*f5c631daSSadaf Ebrahimi                     const PRegisterZ& pg,
6223*f5c631daSSadaf Ebrahimi                     const PRegisterWithLaneSize& pn,
6224*f5c631daSSadaf Ebrahimi                     const PRegisterWithLaneSize& pm) {
6225*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6226*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(pd, pn, pm));
6227*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pd.IsLaneSizeB());
6228*f5c631daSSadaf Ebrahimi   Emit(ORR_p_p_pp_z | Pd(pd) | Pg<13, 10>(pg) | Pn(pn) | Pm(pm));
6229*f5c631daSSadaf Ebrahimi }
6230*f5c631daSSadaf Ebrahimi 
orrs(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)6231*f5c631daSSadaf Ebrahimi void Assembler::orrs(const PRegisterWithLaneSize& pd,
6232*f5c631daSSadaf Ebrahimi                      const PRegisterZ& pg,
6233*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pn,
6234*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pm) {
6235*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6236*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameFormat(pd, pn, pm));
6237*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pd.IsLaneSizeB());
6238*f5c631daSSadaf Ebrahimi   Emit(ORRS_p_p_pp_z | Pd(pd) | Pg<13, 10>(pg) | Pn(pn) | Pm(pm));
6239*f5c631daSSadaf Ebrahimi }
6240*f5c631daSSadaf Ebrahimi 
sel(const PRegisterWithLaneSize & pd,const PRegister & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)6241*f5c631daSSadaf Ebrahimi void Assembler::sel(const PRegisterWithLaneSize& pd,
6242*f5c631daSSadaf Ebrahimi                     const PRegister& pg,
6243*f5c631daSSadaf Ebrahimi                     const PRegisterWithLaneSize& pn,
6244*f5c631daSSadaf Ebrahimi                     const PRegisterWithLaneSize& pm) {
6245*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6246*f5c631daSSadaf Ebrahimi   Emit(SEL_p_p_pp | Pd(pd) | Pg<13, 10>(pg) | Pn(pn) | Pm(pm));
6247*f5c631daSSadaf Ebrahimi }
6248*f5c631daSSadaf Ebrahimi 
6249*f5c631daSSadaf Ebrahimi // SVEPredicateMisc.
6250*f5c631daSSadaf Ebrahimi 
pfalse(const PRegisterWithLaneSize & pd)6251*f5c631daSSadaf Ebrahimi void Assembler::pfalse(const PRegisterWithLaneSize& pd) {
6252*f5c631daSSadaf Ebrahimi   // PFALSE <Pd>.B
6253*f5c631daSSadaf Ebrahimi   //  0010 0101 0001 1000 1110 0100 0000 ....
6254*f5c631daSSadaf Ebrahimi   //  op<23> = 0 | S<22> = 0 | Pd<3:0>
6255*f5c631daSSadaf Ebrahimi 
6256*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6257*f5c631daSSadaf Ebrahimi   // Ignore the lane size, since it makes no difference to the operation.
6258*f5c631daSSadaf Ebrahimi 
6259*f5c631daSSadaf Ebrahimi   Emit(PFALSE_p | Pd(pd));
6260*f5c631daSSadaf Ebrahimi }
6261*f5c631daSSadaf Ebrahimi 
pfirst(const PRegisterWithLaneSize & pd,const PRegister & pg,const PRegisterWithLaneSize & pn)6262*f5c631daSSadaf Ebrahimi void Assembler::pfirst(const PRegisterWithLaneSize& pd,
6263*f5c631daSSadaf Ebrahimi                        const PRegister& pg,
6264*f5c631daSSadaf Ebrahimi                        const PRegisterWithLaneSize& pn) {
6265*f5c631daSSadaf Ebrahimi   // PFIRST <Pdn>.B, <Pg>, <Pdn>.B
6266*f5c631daSSadaf Ebrahimi   //  0010 0101 0101 1000 1100 000. ...0 ....
6267*f5c631daSSadaf Ebrahimi   //  op<23> = 0 | S<22> = 1 | Pg<8:5> | Pdn<3:0>
6268*f5c631daSSadaf Ebrahimi 
6269*f5c631daSSadaf Ebrahimi   USE(pn);
6270*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6271*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pd.Is(pn));
6272*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pd.IsLaneSizeB());
6273*f5c631daSSadaf Ebrahimi 
6274*f5c631daSSadaf Ebrahimi   Emit(PFIRST_p_p_p | Pd(pd) | Pg<8, 5>(pg));
6275*f5c631daSSadaf Ebrahimi }
6276*f5c631daSSadaf Ebrahimi 
pnext(const PRegisterWithLaneSize & pd,const PRegister & pg,const PRegisterWithLaneSize & pn)6277*f5c631daSSadaf Ebrahimi void Assembler::pnext(const PRegisterWithLaneSize& pd,
6278*f5c631daSSadaf Ebrahimi                       const PRegister& pg,
6279*f5c631daSSadaf Ebrahimi                       const PRegisterWithLaneSize& pn) {
6280*f5c631daSSadaf Ebrahimi   // PNEXT <Pdn>.<T>, <Pg>, <Pdn>.<T>
6281*f5c631daSSadaf Ebrahimi   //  0010 0101 ..01 1001 1100 010. ...0 ....
6282*f5c631daSSadaf Ebrahimi   //  size<23:22> | Pg<8:5> | Pdn<3:0>
6283*f5c631daSSadaf Ebrahimi 
6284*f5c631daSSadaf Ebrahimi   USE(pn);
6285*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6286*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pd.Is(pn));
6287*f5c631daSSadaf Ebrahimi 
6288*f5c631daSSadaf Ebrahimi   Emit(PNEXT_p_p_p | SVESize(pd) | Pd(pd) | Pg<8, 5>(pg));
6289*f5c631daSSadaf Ebrahimi }
6290*f5c631daSSadaf Ebrahimi 
ptest(const PRegister & pg,const PRegisterWithLaneSize & pn)6291*f5c631daSSadaf Ebrahimi void Assembler::ptest(const PRegister& pg, const PRegisterWithLaneSize& pn) {
6292*f5c631daSSadaf Ebrahimi   // PTEST <Pg>, <Pn>.B
6293*f5c631daSSadaf Ebrahimi   //  0010 0101 0101 0000 11.. ..0. ...0 0000
6294*f5c631daSSadaf Ebrahimi   //  op<23> = 0 | S<22> = 1 | Pg<13:10> | Pn<8:5> | opc2<3:0> = 0000
6295*f5c631daSSadaf Ebrahimi 
6296*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6297*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pn.IsLaneSizeB());
6298*f5c631daSSadaf Ebrahimi 
6299*f5c631daSSadaf Ebrahimi   Emit(PTEST_p_p | Pg<13, 10>(pg) | Rx<8, 5>(pn));
6300*f5c631daSSadaf Ebrahimi }
6301*f5c631daSSadaf Ebrahimi 
ptrue(const PRegisterWithLaneSize & pd,int pattern)6302*f5c631daSSadaf Ebrahimi void Assembler::ptrue(const PRegisterWithLaneSize& pd, int pattern) {
6303*f5c631daSSadaf Ebrahimi   // PTRUE <Pd>.<T>{, <pattern>}
6304*f5c631daSSadaf Ebrahimi   //  0010 0101 ..01 1000 1110 00.. ...0 ....
6305*f5c631daSSadaf Ebrahimi   //  size<23:22> | S<16> = 0 | pattern<9:5> | Pd<3:0>
6306*f5c631daSSadaf Ebrahimi 
6307*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6308*f5c631daSSadaf Ebrahimi 
6309*f5c631daSSadaf Ebrahimi   Emit(PTRUE_p_s | SVESize(pd) | Pd(pd) | ImmSVEPredicateConstraint(pattern));
6310*f5c631daSSadaf Ebrahimi }
6311*f5c631daSSadaf Ebrahimi 
ptrues(const PRegisterWithLaneSize & pd,int pattern)6312*f5c631daSSadaf Ebrahimi void Assembler::ptrues(const PRegisterWithLaneSize& pd, int pattern) {
6313*f5c631daSSadaf Ebrahimi   // PTRUES <Pd>.<T>{, <pattern>}
6314*f5c631daSSadaf Ebrahimi   //  0010 0101 ..01 1001 1110 00.. ...0 ....
6315*f5c631daSSadaf Ebrahimi   //  size<23:22> | S<16> = 1 | pattern<9:5> | Pd<3:0>
6316*f5c631daSSadaf Ebrahimi 
6317*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6318*f5c631daSSadaf Ebrahimi 
6319*f5c631daSSadaf Ebrahimi   Emit(PTRUES_p_s | SVESize(pd) | Pd(pd) | ImmSVEPredicateConstraint(pattern));
6320*f5c631daSSadaf Ebrahimi }
6321*f5c631daSSadaf Ebrahimi 
rdffr(const PRegisterWithLaneSize & pd)6322*f5c631daSSadaf Ebrahimi void Assembler::rdffr(const PRegisterWithLaneSize& pd) {
6323*f5c631daSSadaf Ebrahimi   // RDFFR <Pd>.B
6324*f5c631daSSadaf Ebrahimi   //  0010 0101 0001 1001 1111 0000 0000 ....
6325*f5c631daSSadaf Ebrahimi   //  op<23> = 0 | S<22> = 0 | Pd<3:0>
6326*f5c631daSSadaf Ebrahimi 
6327*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6328*f5c631daSSadaf Ebrahimi 
6329*f5c631daSSadaf Ebrahimi   Emit(RDFFR_p_f | Pd(pd));
6330*f5c631daSSadaf Ebrahimi }
6331*f5c631daSSadaf Ebrahimi 
rdffr(const PRegisterWithLaneSize & pd,const PRegisterZ & pg)6332*f5c631daSSadaf Ebrahimi void Assembler::rdffr(const PRegisterWithLaneSize& pd, const PRegisterZ& pg) {
6333*f5c631daSSadaf Ebrahimi   // RDFFR <Pd>.B, <Pg>/Z
6334*f5c631daSSadaf Ebrahimi   //  0010 0101 0001 1000 1111 000. ...0 ....
6335*f5c631daSSadaf Ebrahimi   //  op<23> = 0 | S<22> = 0 | Pg<8:5> | Pd<3:0>
6336*f5c631daSSadaf Ebrahimi 
6337*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6338*f5c631daSSadaf Ebrahimi 
6339*f5c631daSSadaf Ebrahimi   Emit(RDFFR_p_p_f | Pd(pd) | Pg<8, 5>(pg));
6340*f5c631daSSadaf Ebrahimi }
6341*f5c631daSSadaf Ebrahimi 
rdffrs(const PRegisterWithLaneSize & pd,const PRegisterZ & pg)6342*f5c631daSSadaf Ebrahimi void Assembler::rdffrs(const PRegisterWithLaneSize& pd, const PRegisterZ& pg) {
6343*f5c631daSSadaf Ebrahimi   // RDFFRS <Pd>.B, <Pg>/Z
6344*f5c631daSSadaf Ebrahimi   //  0010 0101 0101 1000 1111 000. ...0 ....
6345*f5c631daSSadaf Ebrahimi   //  op<23> = 0 | S<22> = 1 | Pg<8:5> | Pd<3:0>
6346*f5c631daSSadaf Ebrahimi 
6347*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6348*f5c631daSSadaf Ebrahimi 
6349*f5c631daSSadaf Ebrahimi   Emit(RDFFRS_p_p_f | Pd(pd) | Pg<8, 5>(pg));
6350*f5c631daSSadaf Ebrahimi }
6351*f5c631daSSadaf Ebrahimi 
6352*f5c631daSSadaf Ebrahimi // SVEPropagateBreak.
6353*f5c631daSSadaf Ebrahimi 
brkpa(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)6354*f5c631daSSadaf Ebrahimi void Assembler::brkpa(const PRegisterWithLaneSize& pd,
6355*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
6356*f5c631daSSadaf Ebrahimi                       const PRegisterWithLaneSize& pn,
6357*f5c631daSSadaf Ebrahimi                       const PRegisterWithLaneSize& pm) {
6358*f5c631daSSadaf Ebrahimi   // BRKPA <Pd>.B, <Pg>/Z, <Pn>.B, <Pm>.B
6359*f5c631daSSadaf Ebrahimi   //  0010 0101 0000 .... 11.. ..0. ...0 ....
6360*f5c631daSSadaf Ebrahimi   //  op<23> = 0 | S<22> = 0 | Pm<19:16> | Pg<13:10> | Pn<8:5> | B<4> = 0 |
6361*f5c631daSSadaf Ebrahimi   //  Pd<3:0>
6362*f5c631daSSadaf Ebrahimi 
6363*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6364*f5c631daSSadaf Ebrahimi 
6365*f5c631daSSadaf Ebrahimi   Emit(BRKPA_p_p_pp | Pd(pd) | Pg<13, 10>(pg) | Pn(pn) | Pm(pm));
6366*f5c631daSSadaf Ebrahimi }
6367*f5c631daSSadaf Ebrahimi 
brkpas(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)6368*f5c631daSSadaf Ebrahimi void Assembler::brkpas(const PRegisterWithLaneSize& pd,
6369*f5c631daSSadaf Ebrahimi                        const PRegisterZ& pg,
6370*f5c631daSSadaf Ebrahimi                        const PRegisterWithLaneSize& pn,
6371*f5c631daSSadaf Ebrahimi                        const PRegisterWithLaneSize& pm) {
6372*f5c631daSSadaf Ebrahimi   // BRKPAS <Pd>.B, <Pg>/Z, <Pn>.B, <Pm>.B
6373*f5c631daSSadaf Ebrahimi   //  0010 0101 0100 .... 11.. ..0. ...0 ....
6374*f5c631daSSadaf Ebrahimi   //  op<23> = 0 | S<22> = 1 | Pm<19:16> | Pg<13:10> | Pn<8:5> | B<4> = 0 |
6375*f5c631daSSadaf Ebrahimi   //  Pd<3:0>
6376*f5c631daSSadaf Ebrahimi 
6377*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6378*f5c631daSSadaf Ebrahimi 
6379*f5c631daSSadaf Ebrahimi   Emit(BRKPAS_p_p_pp | Pd(pd) | Pg<13, 10>(pg) | Pn(pn) | Pm(pm));
6380*f5c631daSSadaf Ebrahimi }
6381*f5c631daSSadaf Ebrahimi 
brkpb(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)6382*f5c631daSSadaf Ebrahimi void Assembler::brkpb(const PRegisterWithLaneSize& pd,
6383*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
6384*f5c631daSSadaf Ebrahimi                       const PRegisterWithLaneSize& pn,
6385*f5c631daSSadaf Ebrahimi                       const PRegisterWithLaneSize& pm) {
6386*f5c631daSSadaf Ebrahimi   // BRKPB <Pd>.B, <Pg>/Z, <Pn>.B, <Pm>.B
6387*f5c631daSSadaf Ebrahimi   //  0010 0101 0000 .... 11.. ..0. ...1 ....
6388*f5c631daSSadaf Ebrahimi   //  op<23> = 0 | S<22> = 0 | Pm<19:16> | Pg<13:10> | Pn<8:5> | B<4> = 1 |
6389*f5c631daSSadaf Ebrahimi   //  Pd<3:0>
6390*f5c631daSSadaf Ebrahimi 
6391*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6392*f5c631daSSadaf Ebrahimi 
6393*f5c631daSSadaf Ebrahimi   Emit(BRKPB_p_p_pp | Pd(pd) | Pg<13, 10>(pg) | Pn(pn) | Pm(pm));
6394*f5c631daSSadaf Ebrahimi }
6395*f5c631daSSadaf Ebrahimi 
brkpbs(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)6396*f5c631daSSadaf Ebrahimi void Assembler::brkpbs(const PRegisterWithLaneSize& pd,
6397*f5c631daSSadaf Ebrahimi                        const PRegisterZ& pg,
6398*f5c631daSSadaf Ebrahimi                        const PRegisterWithLaneSize& pn,
6399*f5c631daSSadaf Ebrahimi                        const PRegisterWithLaneSize& pm) {
6400*f5c631daSSadaf Ebrahimi   // BRKPBS <Pd>.B, <Pg>/Z, <Pn>.B, <Pm>.B
6401*f5c631daSSadaf Ebrahimi   //  0010 0101 0100 .... 11.. ..0. ...1 ....
6402*f5c631daSSadaf Ebrahimi   //  op<23> = 0 | S<22> = 1 | Pm<19:16> | Pg<13:10> | Pn<8:5> | B<4> = 1 |
6403*f5c631daSSadaf Ebrahimi   //  Pd<3:0>
6404*f5c631daSSadaf Ebrahimi 
6405*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6406*f5c631daSSadaf Ebrahimi 
6407*f5c631daSSadaf Ebrahimi   Emit(BRKPBS_p_p_pp | Pd(pd) | Pg<13, 10>(pg) | Pn(pn) | Pm(pm));
6408*f5c631daSSadaf Ebrahimi }
6409*f5c631daSSadaf Ebrahimi 
6410*f5c631daSSadaf Ebrahimi // SVEStackFrameAdjustment.
6411*f5c631daSSadaf Ebrahimi 
addpl(const Register & xd,const Register & xn,int imm6)6412*f5c631daSSadaf Ebrahimi void Assembler::addpl(const Register& xd, const Register& xn, int imm6) {
6413*f5c631daSSadaf Ebrahimi   // ADDPL <Xd|SP>, <Xn|SP>, #<imm>
6414*f5c631daSSadaf Ebrahimi   //  0000 0100 011. .... 0101 0... .... ....
6415*f5c631daSSadaf Ebrahimi   //  op<22> = 1 | Rn<20:16> | imm6<10:5> | Rd<4:0>
6416*f5c631daSSadaf Ebrahimi 
6417*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6418*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(xd.IsX());
6419*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(xn.IsX());
6420*f5c631daSSadaf Ebrahimi 
6421*f5c631daSSadaf Ebrahimi   Emit(ADDPL_r_ri | RdSP(xd) | RmSP(xn) | ImmField<10, 5>(imm6));
6422*f5c631daSSadaf Ebrahimi }
6423*f5c631daSSadaf Ebrahimi 
addvl(const Register & xd,const Register & xn,int imm6)6424*f5c631daSSadaf Ebrahimi void Assembler::addvl(const Register& xd, const Register& xn, int imm6) {
6425*f5c631daSSadaf Ebrahimi   // ADDVL <Xd|SP>, <Xn|SP>, #<imm>
6426*f5c631daSSadaf Ebrahimi   //  0000 0100 001. .... 0101 0... .... ....
6427*f5c631daSSadaf Ebrahimi   //  op<22> = 0 | Rn<20:16> | imm6<10:5> | Rd<4:0>
6428*f5c631daSSadaf Ebrahimi 
6429*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6430*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(xd.IsX());
6431*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(xn.IsX());
6432*f5c631daSSadaf Ebrahimi 
6433*f5c631daSSadaf Ebrahimi   Emit(ADDVL_r_ri | RdSP(xd) | RmSP(xn) | ImmField<10, 5>(imm6));
6434*f5c631daSSadaf Ebrahimi }
6435*f5c631daSSadaf Ebrahimi 
6436*f5c631daSSadaf Ebrahimi // SVEStackFrameSize.
6437*f5c631daSSadaf Ebrahimi 
rdvl(const Register & xd,int imm6)6438*f5c631daSSadaf Ebrahimi void Assembler::rdvl(const Register& xd, int imm6) {
6439*f5c631daSSadaf Ebrahimi   // RDVL <Xd>, #<imm>
6440*f5c631daSSadaf Ebrahimi   //  0000 0100 1011 1111 0101 0... .... ....
6441*f5c631daSSadaf Ebrahimi   //  op<22> = 0 | opc2<20:16> = 11111 | imm6<10:5> | Rd<4:0>
6442*f5c631daSSadaf Ebrahimi 
6443*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6444*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(xd.IsX());
6445*f5c631daSSadaf Ebrahimi 
6446*f5c631daSSadaf Ebrahimi   Emit(RDVL_r_i | Rd(xd) | ImmField<10, 5>(imm6));
6447*f5c631daSSadaf Ebrahimi }
6448*f5c631daSSadaf Ebrahimi 
6449*f5c631daSSadaf Ebrahimi // SVEVectorSelect.
6450*f5c631daSSadaf Ebrahimi 
sel(const ZRegister & zd,const PRegister & pg,const ZRegister & zn,const ZRegister & zm)6451*f5c631daSSadaf Ebrahimi void Assembler::sel(const ZRegister& zd,
6452*f5c631daSSadaf Ebrahimi                     const PRegister& pg,
6453*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
6454*f5c631daSSadaf Ebrahimi                     const ZRegister& zm) {
6455*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6456*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
6457*f5c631daSSadaf Ebrahimi 
6458*f5c631daSSadaf Ebrahimi   Emit(SEL_z_p_zz | SVESize(zd) | Rd(zd) | Pg<13, 10>(pg) | Rn(zn) | Rm(zm));
6459*f5c631daSSadaf Ebrahimi }
6460*f5c631daSSadaf Ebrahimi 
6461*f5c631daSSadaf Ebrahimi // SVEWriteFFR.
6462*f5c631daSSadaf Ebrahimi 
setffr()6463*f5c631daSSadaf Ebrahimi void Assembler::setffr() {
6464*f5c631daSSadaf Ebrahimi   // SETFFR
6465*f5c631daSSadaf Ebrahimi   //  0010 0101 0010 1100 1001 0000 0000 0000
6466*f5c631daSSadaf Ebrahimi   //  opc<23:22> = 00
6467*f5c631daSSadaf Ebrahimi 
6468*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6469*f5c631daSSadaf Ebrahimi 
6470*f5c631daSSadaf Ebrahimi   Emit(SETFFR_f);
6471*f5c631daSSadaf Ebrahimi }
6472*f5c631daSSadaf Ebrahimi 
wrffr(const PRegisterWithLaneSize & pn)6473*f5c631daSSadaf Ebrahimi void Assembler::wrffr(const PRegisterWithLaneSize& pn) {
6474*f5c631daSSadaf Ebrahimi   // WRFFR <Pn>.B
6475*f5c631daSSadaf Ebrahimi   //  0010 0101 0010 1000 1001 000. ...0 0000
6476*f5c631daSSadaf Ebrahimi   //  opc<23:22> = 00 | Pn<8:5>
6477*f5c631daSSadaf Ebrahimi 
6478*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6479*f5c631daSSadaf Ebrahimi 
6480*f5c631daSSadaf Ebrahimi   Emit(WRFFR_f_p | Rx<8, 5>(pn));
6481*f5c631daSSadaf Ebrahimi }
6482*f5c631daSSadaf Ebrahimi 
6483*f5c631daSSadaf Ebrahimi // Aliases.
6484*f5c631daSSadaf Ebrahimi 
bic(const ZRegister & zd,const ZRegister & zn,uint64_t imm)6485*f5c631daSSadaf Ebrahimi void Assembler::bic(const ZRegister& zd, const ZRegister& zn, uint64_t imm) {
6486*f5c631daSSadaf Ebrahimi   and_(zd, zn, ~imm);
6487*f5c631daSSadaf Ebrahimi }
6488*f5c631daSSadaf Ebrahimi 
eon(const ZRegister & zd,const ZRegister & zn,uint64_t imm)6489*f5c631daSSadaf Ebrahimi void Assembler::eon(const ZRegister& zd, const ZRegister& zn, uint64_t imm) {
6490*f5c631daSSadaf Ebrahimi   eor(zd, zn, ~imm);
6491*f5c631daSSadaf Ebrahimi }
6492*f5c631daSSadaf Ebrahimi 
orn(const ZRegister & zd,const ZRegister & zn,uint64_t imm)6493*f5c631daSSadaf Ebrahimi void Assembler::orn(const ZRegister& zd, const ZRegister& zn, uint64_t imm) {
6494*f5c631daSSadaf Ebrahimi   orr(zd, zn, ~imm);
6495*f5c631daSSadaf Ebrahimi }
6496*f5c631daSSadaf Ebrahimi 
6497*f5c631daSSadaf Ebrahimi 
fmov(const ZRegister & zd,const PRegisterM & pg,double imm)6498*f5c631daSSadaf Ebrahimi void Assembler::fmov(const ZRegister& zd, const PRegisterM& pg, double imm) {
6499*f5c631daSSadaf Ebrahimi   if (IsPositiveZero(imm)) {
6500*f5c631daSSadaf Ebrahimi     cpy(zd, pg, 0);
6501*f5c631daSSadaf Ebrahimi   } else {
6502*f5c631daSSadaf Ebrahimi     fcpy(zd, pg, imm);
6503*f5c631daSSadaf Ebrahimi   }
6504*f5c631daSSadaf Ebrahimi }
6505*f5c631daSSadaf Ebrahimi 
fmov(const ZRegister & zd,double imm)6506*f5c631daSSadaf Ebrahimi void Assembler::fmov(const ZRegister& zd, double imm) {
6507*f5c631daSSadaf Ebrahimi   if (IsPositiveZero(imm)) {
6508*f5c631daSSadaf Ebrahimi     dup(zd, imm);
6509*f5c631daSSadaf Ebrahimi   } else {
6510*f5c631daSSadaf Ebrahimi     fdup(zd, imm);
6511*f5c631daSSadaf Ebrahimi   }
6512*f5c631daSSadaf Ebrahimi }
6513*f5c631daSSadaf Ebrahimi 
mov(const PRegister & pd,const PRegister & pn)6514*f5c631daSSadaf Ebrahimi void Assembler::mov(const PRegister& pd, const PRegister& pn) {
6515*f5c631daSSadaf Ebrahimi   // If the inputs carry a lane size, they must match.
6516*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((!pd.HasLaneSize() && !pn.HasLaneSize()) ||
6517*f5c631daSSadaf Ebrahimi               AreSameLaneSize(pd, pn));
6518*f5c631daSSadaf Ebrahimi   orr(pd.VnB(), pn.Zeroing(), pn.VnB(), pn.VnB());
6519*f5c631daSSadaf Ebrahimi }
6520*f5c631daSSadaf Ebrahimi 
mov(const PRegisterWithLaneSize & pd,const PRegisterM & pg,const PRegisterWithLaneSize & pn)6521*f5c631daSSadaf Ebrahimi void Assembler::mov(const PRegisterWithLaneSize& pd,
6522*f5c631daSSadaf Ebrahimi                     const PRegisterM& pg,
6523*f5c631daSSadaf Ebrahimi                     const PRegisterWithLaneSize& pn) {
6524*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6525*f5c631daSSadaf Ebrahimi   sel(pd, pg, pn, pd);
6526*f5c631daSSadaf Ebrahimi }
6527*f5c631daSSadaf Ebrahimi 
mov(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn)6528*f5c631daSSadaf Ebrahimi void Assembler::mov(const PRegisterWithLaneSize& pd,
6529*f5c631daSSadaf Ebrahimi                     const PRegisterZ& pg,
6530*f5c631daSSadaf Ebrahimi                     const PRegisterWithLaneSize& pn) {
6531*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6532*f5c631daSSadaf Ebrahimi   and_(pd, pg, pn, pn);
6533*f5c631daSSadaf Ebrahimi }
6534*f5c631daSSadaf Ebrahimi 
mov(const ZRegister & zd,const PRegister & pg,int imm8,int shift)6535*f5c631daSSadaf Ebrahimi void Assembler::mov(const ZRegister& zd,
6536*f5c631daSSadaf Ebrahimi                     const PRegister& pg,
6537*f5c631daSSadaf Ebrahimi                     int imm8,
6538*f5c631daSSadaf Ebrahimi                     int shift) {
6539*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(pg.IsMerging() || pg.IsZeroing());
6540*f5c631daSSadaf Ebrahimi   cpy(zd, pg, imm8, shift);
6541*f5c631daSSadaf Ebrahimi }
6542*f5c631daSSadaf Ebrahimi 
mov(const ZRegister & zd,const Register & xn)6543*f5c631daSSadaf Ebrahimi void Assembler::mov(const ZRegister& zd, const Register& xn) { dup(zd, xn); }
6544*f5c631daSSadaf Ebrahimi 
mov(const ZRegister & zd,const VRegister & vn)6545*f5c631daSSadaf Ebrahimi void Assembler::mov(const ZRegister& zd, const VRegister& vn) {
6546*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(vn.IsScalar());
6547*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, vn));
6548*f5c631daSSadaf Ebrahimi   dup(zd, vn.Z().WithSameLaneSizeAs(vn), 0);
6549*f5c631daSSadaf Ebrahimi }
6550*f5c631daSSadaf Ebrahimi 
mov(const ZRegister & zd,const ZRegister & zn)6551*f5c631daSSadaf Ebrahimi void Assembler::mov(const ZRegister& zd, const ZRegister& zn) {
6552*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
6553*f5c631daSSadaf Ebrahimi   orr(zd.VnD(), zn.VnD(), zn.VnD());
6554*f5c631daSSadaf Ebrahimi }
6555*f5c631daSSadaf Ebrahimi 
mov(const ZRegister & zd,const ZRegister & zn,unsigned index)6556*f5c631daSSadaf Ebrahimi void Assembler::mov(const ZRegister& zd, const ZRegister& zn, unsigned index) {
6557*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
6558*f5c631daSSadaf Ebrahimi   dup(zd, zn, index);
6559*f5c631daSSadaf Ebrahimi }
6560*f5c631daSSadaf Ebrahimi 
mov(const ZRegister & zd,const PRegisterM & pg,const Register & rn)6561*f5c631daSSadaf Ebrahimi void Assembler::mov(const ZRegister& zd,
6562*f5c631daSSadaf Ebrahimi                     const PRegisterM& pg,
6563*f5c631daSSadaf Ebrahimi                     const Register& rn) {
6564*f5c631daSSadaf Ebrahimi   cpy(zd, pg, rn);
6565*f5c631daSSadaf Ebrahimi }
6566*f5c631daSSadaf Ebrahimi 
mov(const ZRegister & zd,const PRegisterM & pg,const VRegister & vn)6567*f5c631daSSadaf Ebrahimi void Assembler::mov(const ZRegister& zd,
6568*f5c631daSSadaf Ebrahimi                     const PRegisterM& pg,
6569*f5c631daSSadaf Ebrahimi                     const VRegister& vn) {
6570*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(vn.IsScalar());
6571*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, vn));
6572*f5c631daSSadaf Ebrahimi   cpy(zd, pg, vn);
6573*f5c631daSSadaf Ebrahimi }
6574*f5c631daSSadaf Ebrahimi 
mov(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)6575*f5c631daSSadaf Ebrahimi void Assembler::mov(const ZRegister& zd,
6576*f5c631daSSadaf Ebrahimi                     const PRegisterM& pg,
6577*f5c631daSSadaf Ebrahimi                     const ZRegister& zn) {
6578*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
6579*f5c631daSSadaf Ebrahimi   sel(zd, pg, zn, zd);
6580*f5c631daSSadaf Ebrahimi }
6581*f5c631daSSadaf Ebrahimi 
mov(const ZRegister & zd,uint64_t imm)6582*f5c631daSSadaf Ebrahimi void Assembler::mov(const ZRegister& zd, uint64_t imm) {
6583*f5c631daSSadaf Ebrahimi   // Mov is an alias of dupm for certain values of imm. Whilst this matters in
6584*f5c631daSSadaf Ebrahimi   // the disassembler, for the assembler, we don't distinguish between the
6585*f5c631daSSadaf Ebrahimi   // two mnemonics, and simply call dupm.
6586*f5c631daSSadaf Ebrahimi   dupm(zd, imm);
6587*f5c631daSSadaf Ebrahimi }
6588*f5c631daSSadaf Ebrahimi 
mov(const ZRegister & zd,int imm8,int shift)6589*f5c631daSSadaf Ebrahimi void Assembler::mov(const ZRegister& zd, int imm8, int shift) {
6590*f5c631daSSadaf Ebrahimi   dup(zd, imm8, shift);
6591*f5c631daSSadaf Ebrahimi }
6592*f5c631daSSadaf Ebrahimi 
movs(const PRegister & pd,const PRegister & pn)6593*f5c631daSSadaf Ebrahimi void Assembler::movs(const PRegister& pd, const PRegister& pn) {
6594*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6595*f5c631daSSadaf Ebrahimi   orrs(pd.VnB(), pn.Zeroing(), pn.VnB(), pn.VnB());
6596*f5c631daSSadaf Ebrahimi }
6597*f5c631daSSadaf Ebrahimi 
movs(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn)6598*f5c631daSSadaf Ebrahimi void Assembler::movs(const PRegisterWithLaneSize& pd,
6599*f5c631daSSadaf Ebrahimi                      const PRegisterZ& pg,
6600*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pn) {
6601*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6602*f5c631daSSadaf Ebrahimi   ands(pd, pg, pn, pn);
6603*f5c631daSSadaf Ebrahimi }
6604*f5c631daSSadaf Ebrahimi 
not_(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn)6605*f5c631daSSadaf Ebrahimi void Assembler::not_(const PRegisterWithLaneSize& pd,
6606*f5c631daSSadaf Ebrahimi                      const PRegisterZ& pg,
6607*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pn) {
6608*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6609*f5c631daSSadaf Ebrahimi   eor(pd, pg, pn, pg.VnB());
6610*f5c631daSSadaf Ebrahimi }
6611*f5c631daSSadaf Ebrahimi 
nots(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn)6612*f5c631daSSadaf Ebrahimi void Assembler::nots(const PRegisterWithLaneSize& pd,
6613*f5c631daSSadaf Ebrahimi                      const PRegisterZ& pg,
6614*f5c631daSSadaf Ebrahimi                      const PRegisterWithLaneSize& pn) {
6615*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
6616*f5c631daSSadaf Ebrahimi   eors(pd, pg, pn, pg.VnB());
6617*f5c631daSSadaf Ebrahimi }
6618*f5c631daSSadaf Ebrahimi 
6619*f5c631daSSadaf Ebrahimi // SVE2
6620*f5c631daSSadaf Ebrahimi 
adclb(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)6621*f5c631daSSadaf Ebrahimi void Assembler::adclb(const ZRegister& zda,
6622*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
6623*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
6624*f5c631daSSadaf Ebrahimi   // ADCLB <Zda>.<T>, <Zn>.<T>, <Zm>.<T>
6625*f5c631daSSadaf Ebrahimi   //  0100 0101 0.0. .... 1101 00.. .... ....
6626*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | T<10> | Zn<9:5> | Zda<4:0>
6627*f5c631daSSadaf Ebrahimi 
6628*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
6629*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn, zm));
6630*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.IsLaneSizeS() || zda.IsLaneSizeD());
6631*f5c631daSSadaf Ebrahimi 
6632*f5c631daSSadaf Ebrahimi   Instr sz = zda.IsLaneSizeD() ? (1 << 22) : 0;
6633*f5c631daSSadaf Ebrahimi   Emit(0x4500d000 | sz | Rd(zda) | Rn(zn) | Rm(zm));
6634*f5c631daSSadaf Ebrahimi }
6635*f5c631daSSadaf Ebrahimi 
adclt(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)6636*f5c631daSSadaf Ebrahimi void Assembler::adclt(const ZRegister& zda,
6637*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
6638*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
6639*f5c631daSSadaf Ebrahimi   // ADCLT <Zda>.<T>, <Zn>.<T>, <Zm>.<T>
6640*f5c631daSSadaf Ebrahimi   //  0100 0101 0.0. .... 1101 01.. .... ....
6641*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | T<10> | Zn<9:5> | Zda<4:0>
6642*f5c631daSSadaf Ebrahimi 
6643*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
6644*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn, zm));
6645*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.IsLaneSizeS() || zda.IsLaneSizeD());
6646*f5c631daSSadaf Ebrahimi 
6647*f5c631daSSadaf Ebrahimi   Instr sz = zda.IsLaneSizeD() ? (1 << 22) : 0;
6648*f5c631daSSadaf Ebrahimi   Emit(0x4500d400 | sz | Rd(zda) | Rn(zn) | Rm(zm));
6649*f5c631daSSadaf Ebrahimi }
6650*f5c631daSSadaf Ebrahimi 
addhnb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6651*f5c631daSSadaf Ebrahimi void Assembler::addhnb(const ZRegister& zd,
6652*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
6653*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
6654*f5c631daSSadaf Ebrahimi   // ADDHNB <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
6655*f5c631daSSadaf Ebrahimi   //  0100 0101 ..1. .... 0110 00.. .... ....
6656*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<12> | R<11> | T<10> | Zn<9:5> | Zd<4:0>
6657*f5c631daSSadaf Ebrahimi 
6658*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
6659*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
6660*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() == (zd.GetLaneSizeInBytes() * 2));
6661*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() != kBRegSizeInBytes);
6662*f5c631daSSadaf Ebrahimi 
6663*f5c631daSSadaf Ebrahimi   Emit(0x45206000 | SVESize(zn) | Rd(zd) | Rn(zn) | Rm(zm));
6664*f5c631daSSadaf Ebrahimi }
6665*f5c631daSSadaf Ebrahimi 
addhnt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6666*f5c631daSSadaf Ebrahimi void Assembler::addhnt(const ZRegister& zd,
6667*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
6668*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
6669*f5c631daSSadaf Ebrahimi   // ADDHNT <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
6670*f5c631daSSadaf Ebrahimi   //  0100 0101 ..1. .... 0110 01.. .... ....
6671*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<12> | R<11> | T<10> | Zn<9:5> | Zd<4:0>
6672*f5c631daSSadaf Ebrahimi 
6673*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
6674*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
6675*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() == (zd.GetLaneSizeInBytes() * 2));
6676*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() != kBRegSizeInBytes);
6677*f5c631daSSadaf Ebrahimi 
6678*f5c631daSSadaf Ebrahimi   Emit(0x45206400 | SVESize(zn) | Rd(zd) | Rn(zn) | Rm(zm));
6679*f5c631daSSadaf Ebrahimi }
6680*f5c631daSSadaf Ebrahimi 
addp(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)6681*f5c631daSSadaf Ebrahimi void Assembler::addp(const ZRegister& zd,
6682*f5c631daSSadaf Ebrahimi                      const PRegisterM& pg,
6683*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
6684*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
6685*f5c631daSSadaf Ebrahimi   // ADDP <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
6686*f5c631daSSadaf Ebrahimi   //  0100 0100 ..01 0001 101. .... .... ....
6687*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:17> | U<16> | Pg<12:10> | Zm<9:5> | Zdn<4:0>
6688*f5c631daSSadaf Ebrahimi 
6689*f5c631daSSadaf Ebrahimi   USE(zn);
6690*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
6691*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
6692*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
6693*f5c631daSSadaf Ebrahimi 
6694*f5c631daSSadaf Ebrahimi   Emit(0x4411a000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
6695*f5c631daSSadaf Ebrahimi }
6696*f5c631daSSadaf Ebrahimi 
bcax(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm,const ZRegister & zk)6697*f5c631daSSadaf Ebrahimi void Assembler::bcax(const ZRegister& zd,
6698*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
6699*f5c631daSSadaf Ebrahimi                      const ZRegister& zm,
6700*f5c631daSSadaf Ebrahimi                      const ZRegister& zk) {
6701*f5c631daSSadaf Ebrahimi   // BCAX <Zdn>.D, <Zdn>.D, <Zm>.D, <Zk>.D
6702*f5c631daSSadaf Ebrahimi   //  0000 0100 011. .... 0011 10.. .... ....
6703*f5c631daSSadaf Ebrahimi   //  opc<23:22> | Zm<20:16> | o2<10> | Zk<9:5> | Zdn<4:0>
6704*f5c631daSSadaf Ebrahimi 
6705*f5c631daSSadaf Ebrahimi   USE(zn);
6706*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
6707*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
6708*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm, zk));
6709*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeD());
6710*f5c631daSSadaf Ebrahimi 
6711*f5c631daSSadaf Ebrahimi   Emit(0x04603800 | Rd(zd) | Rm(zm) | Rn(zk));
6712*f5c631daSSadaf Ebrahimi }
6713*f5c631daSSadaf Ebrahimi 
bdep(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6714*f5c631daSSadaf Ebrahimi void Assembler::bdep(const ZRegister& zd,
6715*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
6716*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
6717*f5c631daSSadaf Ebrahimi   // BDEP <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
6718*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 1011 01.. .... ....
6719*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<11:10> | Zn<9:5> | Zd<4:0>
6720*f5c631daSSadaf Ebrahimi 
6721*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
6722*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVEBitPerm));
6723*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
6724*f5c631daSSadaf Ebrahimi 
6725*f5c631daSSadaf Ebrahimi   Emit(0x4500b400 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
6726*f5c631daSSadaf Ebrahimi }
6727*f5c631daSSadaf Ebrahimi 
bext(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6728*f5c631daSSadaf Ebrahimi void Assembler::bext(const ZRegister& zd,
6729*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
6730*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
6731*f5c631daSSadaf Ebrahimi   // BEXT <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
6732*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 1011 00.. .... ....
6733*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<11:10> | Zn<9:5> | Zd<4:0>
6734*f5c631daSSadaf Ebrahimi 
6735*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
6736*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVEBitPerm));
6737*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
6738*f5c631daSSadaf Ebrahimi 
6739*f5c631daSSadaf Ebrahimi   Emit(0x4500b000 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
6740*f5c631daSSadaf Ebrahimi }
6741*f5c631daSSadaf Ebrahimi 
bgrp(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6742*f5c631daSSadaf Ebrahimi void Assembler::bgrp(const ZRegister& zd,
6743*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
6744*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
6745*f5c631daSSadaf Ebrahimi   // BGRP <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
6746*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 1011 10.. .... ....
6747*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<11:10> | Zn<9:5> | Zd<4:0>
6748*f5c631daSSadaf Ebrahimi 
6749*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
6750*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVEBitPerm));
6751*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
6752*f5c631daSSadaf Ebrahimi 
6753*f5c631daSSadaf Ebrahimi   Emit(0x4500b800 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
6754*f5c631daSSadaf Ebrahimi }
6755*f5c631daSSadaf Ebrahimi 
bsl(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm,const ZRegister & zk)6756*f5c631daSSadaf Ebrahimi void Assembler::bsl(const ZRegister& zd,
6757*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
6758*f5c631daSSadaf Ebrahimi                     const ZRegister& zm,
6759*f5c631daSSadaf Ebrahimi                     const ZRegister& zk) {
6760*f5c631daSSadaf Ebrahimi   // BSL <Zdn>.D, <Zdn>.D, <Zm>.D, <Zk>.D
6761*f5c631daSSadaf Ebrahimi   //  0000 0100 001. .... 0011 11.. .... ....
6762*f5c631daSSadaf Ebrahimi   //  opc<23:22> | Zm<20:16> | o2<10> | Zk<9:5> | Zdn<4:0>
6763*f5c631daSSadaf Ebrahimi 
6764*f5c631daSSadaf Ebrahimi   USE(zn);
6765*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
6766*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
6767*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm, zk));
6768*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeD());
6769*f5c631daSSadaf Ebrahimi 
6770*f5c631daSSadaf Ebrahimi   Emit(0x04203c00 | Rd(zd) | Rm(zm) | Rn(zk));
6771*f5c631daSSadaf Ebrahimi }
6772*f5c631daSSadaf Ebrahimi 
bsl1n(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm,const ZRegister & zk)6773*f5c631daSSadaf Ebrahimi void Assembler::bsl1n(const ZRegister& zd,
6774*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
6775*f5c631daSSadaf Ebrahimi                       const ZRegister& zm,
6776*f5c631daSSadaf Ebrahimi                       const ZRegister& zk) {
6777*f5c631daSSadaf Ebrahimi   // BSL1N <Zdn>.D, <Zdn>.D, <Zm>.D, <Zk>.D
6778*f5c631daSSadaf Ebrahimi   //  0000 0100 011. .... 0011 11.. .... ....
6779*f5c631daSSadaf Ebrahimi   //  opc<23:22> | Zm<20:16> | o2<10> | Zk<9:5> | Zdn<4:0>
6780*f5c631daSSadaf Ebrahimi 
6781*f5c631daSSadaf Ebrahimi   USE(zn);
6782*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
6783*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
6784*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm, zk));
6785*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeD());
6786*f5c631daSSadaf Ebrahimi 
6787*f5c631daSSadaf Ebrahimi   Emit(0x04603c00 | Rd(zd) | Rm(zm) | Rn(zk));
6788*f5c631daSSadaf Ebrahimi }
6789*f5c631daSSadaf Ebrahimi 
bsl2n(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm,const ZRegister & zk)6790*f5c631daSSadaf Ebrahimi void Assembler::bsl2n(const ZRegister& zd,
6791*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
6792*f5c631daSSadaf Ebrahimi                       const ZRegister& zm,
6793*f5c631daSSadaf Ebrahimi                       const ZRegister& zk) {
6794*f5c631daSSadaf Ebrahimi   // BSL2N <Zdn>.D, <Zdn>.D, <Zm>.D, <Zk>.D
6795*f5c631daSSadaf Ebrahimi   //  0000 0100 101. .... 0011 11.. .... ....
6796*f5c631daSSadaf Ebrahimi   //  opc<23:22> | Zm<20:16> | o2<10> | Zk<9:5> | Zdn<4:0>
6797*f5c631daSSadaf Ebrahimi 
6798*f5c631daSSadaf Ebrahimi   USE(zn);
6799*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
6800*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
6801*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm, zk));
6802*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeD());
6803*f5c631daSSadaf Ebrahimi 
6804*f5c631daSSadaf Ebrahimi   Emit(0x04a03c00 | Rd(zd) | Rm(zm) | Rn(zk));
6805*f5c631daSSadaf Ebrahimi }
6806*f5c631daSSadaf Ebrahimi 
cadd(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm,int rot)6807*f5c631daSSadaf Ebrahimi void Assembler::cadd(const ZRegister& zd,
6808*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
6809*f5c631daSSadaf Ebrahimi                      const ZRegister& zm,
6810*f5c631daSSadaf Ebrahimi                      int rot) {
6811*f5c631daSSadaf Ebrahimi   // CADD <Zdn>.<T>, <Zdn>.<T>, <Zm>.<T>, <const>
6812*f5c631daSSadaf Ebrahimi   //  0100 0101 ..00 0000 1101 1... .... ....
6813*f5c631daSSadaf Ebrahimi   //  size<23:22> | op<16> | rot<10> | Zm<9:5> | Zdn<4:0>
6814*f5c631daSSadaf Ebrahimi 
6815*f5c631daSSadaf Ebrahimi   USE(zn);
6816*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
6817*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
6818*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
6819*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((rot == 90) || (rot == 270));
6820*f5c631daSSadaf Ebrahimi 
6821*f5c631daSSadaf Ebrahimi   Instr rotate_bit = (rot == 90) ? 0 : (1 << 10);
6822*f5c631daSSadaf Ebrahimi   Emit(0x4500d800 | rotate_bit | SVESize(zd) | Rd(zd) | Rn(zm));
6823*f5c631daSSadaf Ebrahimi }
6824*f5c631daSSadaf Ebrahimi 
cdot(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm,int index,int rot)6825*f5c631daSSadaf Ebrahimi void Assembler::cdot(const ZRegister& zda,
6826*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
6827*f5c631daSSadaf Ebrahimi                      const ZRegister& zm,
6828*f5c631daSSadaf Ebrahimi                      int index,
6829*f5c631daSSadaf Ebrahimi                      int rot) {
6830*f5c631daSSadaf Ebrahimi   // CDOT <Zda>.D, <Zn>.H, <Zm>.H[<imm>], <const>
6831*f5c631daSSadaf Ebrahimi   //  0100 0100 111. .... 0100 .... .... ....
6832*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<20:16> | rot<11:10> | Zn<9:5> | Zda<4:0>
6833*f5c631daSSadaf Ebrahimi 
6834*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
6835*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((rot == 0) || (rot == 90) || (rot == 180) || (rot == 270));
6836*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
6837*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.IsLaneSizeS() || zda.IsLaneSizeD());
6838*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 4));
6839*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(index >= 0);
6840*f5c631daSSadaf Ebrahimi 
6841*f5c631daSSadaf Ebrahimi   Instr zm_and_idx = 0;
6842*f5c631daSSadaf Ebrahimi   if (zm.IsLaneSizeB()) {
6843*f5c631daSSadaf Ebrahimi     // Zm<18:16> | i2<20:19>
6844*f5c631daSSadaf Ebrahimi     VIXL_ASSERT((zm.GetCode() <= 7) && (index <= 3));
6845*f5c631daSSadaf Ebrahimi     zm_and_idx = (index << 19) | Rx<18, 16>(zm);
6846*f5c631daSSadaf Ebrahimi   } else {
6847*f5c631daSSadaf Ebrahimi     // Zm<19:16> | i1<20>
6848*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zm.IsLaneSizeH());
6849*f5c631daSSadaf Ebrahimi     VIXL_ASSERT((zm.GetCode() <= 15) && (index <= 1));
6850*f5c631daSSadaf Ebrahimi     zm_and_idx = (index << 20) | Rx<19, 16>(zm);
6851*f5c631daSSadaf Ebrahimi   }
6852*f5c631daSSadaf Ebrahimi 
6853*f5c631daSSadaf Ebrahimi   Instr rotate_bits = (rot / 90) << 10;
6854*f5c631daSSadaf Ebrahimi   Emit(0x44a04000 | zm_and_idx | rotate_bits | SVESize(zda) | Rd(zda) | Rn(zn));
6855*f5c631daSSadaf Ebrahimi }
6856*f5c631daSSadaf Ebrahimi 
cdot(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm,int rot)6857*f5c631daSSadaf Ebrahimi void Assembler::cdot(const ZRegister& zda,
6858*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
6859*f5c631daSSadaf Ebrahimi                      const ZRegister& zm,
6860*f5c631daSSadaf Ebrahimi                      int rot) {
6861*f5c631daSSadaf Ebrahimi   // CDOT <Zda>.<T>, <Zn>.<Tb>, <Zm>.<Tb>, <const>
6862*f5c631daSSadaf Ebrahimi   //  0100 0100 ..0. .... 0001 .... .... ....
6863*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | rot<11:10> | Zn<9:5> | Zda<4:0>
6864*f5c631daSSadaf Ebrahimi 
6865*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
6866*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((rot == 0) || (rot == 90) || (rot == 180) || (rot == 270));
6867*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
6868*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.IsLaneSizeS() || zda.IsLaneSizeD());
6869*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 4));
6870*f5c631daSSadaf Ebrahimi 
6871*f5c631daSSadaf Ebrahimi   Instr rotate_bits = (rot / 90) << 10;
6872*f5c631daSSadaf Ebrahimi   Emit(0x44001000 | rotate_bits | SVESize(zda) | Rd(zda) | Rn(zn) | Rm(zm));
6873*f5c631daSSadaf Ebrahimi }
6874*f5c631daSSadaf Ebrahimi 
cmla(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm,int index,int rot)6875*f5c631daSSadaf Ebrahimi void Assembler::cmla(const ZRegister& zda,
6876*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
6877*f5c631daSSadaf Ebrahimi                      const ZRegister& zm,
6878*f5c631daSSadaf Ebrahimi                      int index,
6879*f5c631daSSadaf Ebrahimi                      int rot) {
6880*f5c631daSSadaf Ebrahimi   // CMLA <Zda>.H, <Zn>.H, <Zm>.H[<imm>], <const>
6881*f5c631daSSadaf Ebrahimi   //  0100 0100 101. .... 0110 .... .... ....
6882*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<20:16> | rot<11:10> | Zn<9:5> | Zda<4:0>
6883*f5c631daSSadaf Ebrahimi 
6884*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
6885*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn, zm));
6886*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((rot == 0) || (rot == 90) || (rot == 180) || (rot == 270));
6887*f5c631daSSadaf Ebrahimi 
6888*f5c631daSSadaf Ebrahimi   Instr rotate_bit = (rot / 90) << 10;
6889*f5c631daSSadaf Ebrahimi   Emit(0x44a06000 | SVEMulComplexIndexHelper(zm, index) | rotate_bit | Rd(zda) |
6890*f5c631daSSadaf Ebrahimi        Rn(zn));
6891*f5c631daSSadaf Ebrahimi }
6892*f5c631daSSadaf Ebrahimi 
cmla(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm,int rot)6893*f5c631daSSadaf Ebrahimi void Assembler::cmla(const ZRegister& zda,
6894*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
6895*f5c631daSSadaf Ebrahimi                      const ZRegister& zm,
6896*f5c631daSSadaf Ebrahimi                      int rot) {
6897*f5c631daSSadaf Ebrahimi   // CMLA <Zda>.<T>, <Zn>.<T>, <Zm>.<T>, <const>
6898*f5c631daSSadaf Ebrahimi   //  0100 0100 ..0. .... 0010 .... .... ....
6899*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<12> | rot<11:10> | Zn<9:5> | Zda<4:0>
6900*f5c631daSSadaf Ebrahimi 
6901*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
6902*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn, zm));
6903*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((rot == 0) || (rot == 90) || (rot == 180) || (rot == 270));
6904*f5c631daSSadaf Ebrahimi 
6905*f5c631daSSadaf Ebrahimi   Instr rotate_bit = (rot / 90) << 10;
6906*f5c631daSSadaf Ebrahimi   Emit(0x44002000 | rotate_bit | SVESize(zda) | Rd(zda) | Rn(zn) | Rm(zm));
6907*f5c631daSSadaf Ebrahimi }
6908*f5c631daSSadaf Ebrahimi 
eor3(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm,const ZRegister & zk)6909*f5c631daSSadaf Ebrahimi void Assembler::eor3(const ZRegister& zd,
6910*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
6911*f5c631daSSadaf Ebrahimi                      const ZRegister& zm,
6912*f5c631daSSadaf Ebrahimi                      const ZRegister& zk) {
6913*f5c631daSSadaf Ebrahimi   // EOR3 <Zdn>.D, <Zdn>.D, <Zm>.D, <Zk>.D
6914*f5c631daSSadaf Ebrahimi   //  0000 0100 001. .... 0011 10.. .... ....
6915*f5c631daSSadaf Ebrahimi   //  opc<23:22> | Zm<20:16> | o2<10> | Zk<9:5> | Zdn<4:0>
6916*f5c631daSSadaf Ebrahimi 
6917*f5c631daSSadaf Ebrahimi   USE(zn);
6918*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
6919*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
6920*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm, zk));
6921*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeD());
6922*f5c631daSSadaf Ebrahimi 
6923*f5c631daSSadaf Ebrahimi   Emit(0x04203800 | Rd(zd) | Rm(zm) | Rn(zk));
6924*f5c631daSSadaf Ebrahimi }
6925*f5c631daSSadaf Ebrahimi 
eorbt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6926*f5c631daSSadaf Ebrahimi void Assembler::eorbt(const ZRegister& zd,
6927*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
6928*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
6929*f5c631daSSadaf Ebrahimi   // EORBT <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
6930*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 1001 00.. .... ....
6931*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | tb<10> | Zn<9:5> | Zd<4:0>
6932*f5c631daSSadaf Ebrahimi 
6933*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
6934*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
6935*f5c631daSSadaf Ebrahimi 
6936*f5c631daSSadaf Ebrahimi   Emit(0x45009000 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
6937*f5c631daSSadaf Ebrahimi }
6938*f5c631daSSadaf Ebrahimi 
eortb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6939*f5c631daSSadaf Ebrahimi void Assembler::eortb(const ZRegister& zd,
6940*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
6941*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
6942*f5c631daSSadaf Ebrahimi   // EORTB <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
6943*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 1001 01.. .... ....
6944*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | tb<10> | Zn<9:5> | Zd<4:0>
6945*f5c631daSSadaf Ebrahimi 
6946*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
6947*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
6948*f5c631daSSadaf Ebrahimi 
6949*f5c631daSSadaf Ebrahimi   Emit(0x45009400 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
6950*f5c631daSSadaf Ebrahimi }
6951*f5c631daSSadaf Ebrahimi 
faddp(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)6952*f5c631daSSadaf Ebrahimi void Assembler::faddp(const ZRegister& zd,
6953*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
6954*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
6955*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
6956*f5c631daSSadaf Ebrahimi   // FADDP <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
6957*f5c631daSSadaf Ebrahimi   //  0110 0100 ..01 0000 100. .... .... ....
6958*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> | Pg<12:10> | Zm<9:5> | Zdn<4:0>
6959*f5c631daSSadaf Ebrahimi 
6960*f5c631daSSadaf Ebrahimi   USE(zn);
6961*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
6962*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
6963*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
6964*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
6965*f5c631daSSadaf Ebrahimi 
6966*f5c631daSSadaf Ebrahimi   Emit(0x64108000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
6967*f5c631daSSadaf Ebrahimi }
6968*f5c631daSSadaf Ebrahimi 
fcvtlt(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)6969*f5c631daSSadaf Ebrahimi void Assembler::fcvtlt(const ZRegister& zd,
6970*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
6971*f5c631daSSadaf Ebrahimi                        const ZRegister& zn) {
6972*f5c631daSSadaf Ebrahimi   // FCVTLT <Zd>.S, <Pg>/M, <Zn>.H
6973*f5c631daSSadaf Ebrahimi   //  0110 0100 1000 1001 101. .... .... ....
6974*f5c631daSSadaf Ebrahimi   //  opc<23:22> | opc2<17:16> | Pg<12:10> | Zn<9:5> | Zd<4:0>
6975*f5c631daSSadaf Ebrahimi 
6976*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
6977*f5c631daSSadaf Ebrahimi 
6978*f5c631daSSadaf Ebrahimi   Instr op;
6979*f5c631daSSadaf Ebrahimi   if (zd.IsLaneSizeD() && zn.IsLaneSizeS()) {
6980*f5c631daSSadaf Ebrahimi     op = 0x64cba000;
6981*f5c631daSSadaf Ebrahimi   } else {
6982*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zd.IsLaneSizeS() && zn.IsLaneSizeH());
6983*f5c631daSSadaf Ebrahimi     op = 0x6489a000;
6984*f5c631daSSadaf Ebrahimi   }
6985*f5c631daSSadaf Ebrahimi 
6986*f5c631daSSadaf Ebrahimi   Emit(op | Rd(zd) | PgLow8(pg) | Rn(zn));
6987*f5c631daSSadaf Ebrahimi }
6988*f5c631daSSadaf Ebrahimi 
fcvtnt(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)6989*f5c631daSSadaf Ebrahimi void Assembler::fcvtnt(const ZRegister& zd,
6990*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
6991*f5c631daSSadaf Ebrahimi                        const ZRegister& zn) {
6992*f5c631daSSadaf Ebrahimi   // FCVTNT <Zd>.S, <Pg>/M, <Zn>.D
6993*f5c631daSSadaf Ebrahimi   //  0110 0100 1100 1010 101. .... .... ....
6994*f5c631daSSadaf Ebrahimi   //  opc<23:22> | opc2<17:16> | Pg<12:10> | Zn<9:5> | Zd<4:0>
6995*f5c631daSSadaf Ebrahimi 
6996*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
6997*f5c631daSSadaf Ebrahimi 
6998*f5c631daSSadaf Ebrahimi   Instr op;
6999*f5c631daSSadaf Ebrahimi   if (zd.IsLaneSizeS() && zn.IsLaneSizeD()) {
7000*f5c631daSSadaf Ebrahimi     op = 0x64caa000;
7001*f5c631daSSadaf Ebrahimi   } else {
7002*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zd.IsLaneSizeH() && zn.IsLaneSizeS());
7003*f5c631daSSadaf Ebrahimi     op = 0x6488a000;
7004*f5c631daSSadaf Ebrahimi   }
7005*f5c631daSSadaf Ebrahimi   Emit(op | Rd(zd) | PgLow8(pg) | Rn(zn));
7006*f5c631daSSadaf Ebrahimi }
7007*f5c631daSSadaf Ebrahimi 
fcvtx(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)7008*f5c631daSSadaf Ebrahimi void Assembler::fcvtx(const ZRegister& zd,
7009*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
7010*f5c631daSSadaf Ebrahimi                       const ZRegister& zn) {
7011*f5c631daSSadaf Ebrahimi   // FCVTX <Zd>.S, <Pg>/M, <Zn>.D
7012*f5c631daSSadaf Ebrahimi   //  0110 0101 0000 1010 101. .... .... ....
7013*f5c631daSSadaf Ebrahimi   //  opc<23:22> | opc2<17:16> | Pg<12:10> | Zn<9:5> | Zd<4:0>
7014*f5c631daSSadaf Ebrahimi 
7015*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7016*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeS() && zn.IsLaneSizeD());
7017*f5c631daSSadaf Ebrahimi 
7018*f5c631daSSadaf Ebrahimi   Emit(0x650aa000 | Rd(zd) | PgLow8(pg) | Rn(zn));
7019*f5c631daSSadaf Ebrahimi }
7020*f5c631daSSadaf Ebrahimi 
fcvtxnt(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)7021*f5c631daSSadaf Ebrahimi void Assembler::fcvtxnt(const ZRegister& zd,
7022*f5c631daSSadaf Ebrahimi                         const PRegisterM& pg,
7023*f5c631daSSadaf Ebrahimi                         const ZRegister& zn) {
7024*f5c631daSSadaf Ebrahimi   // FCVTXNT <Zd>.S, <Pg>/M, <Zn>.D
7025*f5c631daSSadaf Ebrahimi   //  0110 0100 0000 1010 101. .... .... ....
7026*f5c631daSSadaf Ebrahimi   //  opc<23:22> | opc2<17:16> | Pg<12:10> | Zn<9:5> | Zd<4:0>
7027*f5c631daSSadaf Ebrahimi 
7028*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7029*f5c631daSSadaf Ebrahimi 
7030*f5c631daSSadaf Ebrahimi   Emit(0x640aa000 | Rd(zd) | PgLow8(pg) | Rn(zn));
7031*f5c631daSSadaf Ebrahimi }
7032*f5c631daSSadaf Ebrahimi 
flogb(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)7033*f5c631daSSadaf Ebrahimi void Assembler::flogb(const ZRegister& zd,
7034*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
7035*f5c631daSSadaf Ebrahimi                       const ZRegister& zn) {
7036*f5c631daSSadaf Ebrahimi   // FLOGB <Zd>.<T>, <Pg>/M, <Zn>.<T>
7037*f5c631daSSadaf Ebrahimi   //  0110 0101 0001 1..0 101. .... .... ....
7038*f5c631daSSadaf Ebrahimi   //  opc<23:22> | opc2<18:17> | U<16> | Pg<12:10> | Zn<9:5> | Zd<4:0> | size<>
7039*f5c631daSSadaf Ebrahimi 
7040*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7041*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
7042*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zd.IsLaneSizeB());
7043*f5c631daSSadaf Ebrahimi 
7044*f5c631daSSadaf Ebrahimi   // Size field is encoded in bits <18:17> rather than <23:22>.
7045*f5c631daSSadaf Ebrahimi   Instr size = SVESize(zd) >> 5;
7046*f5c631daSSadaf Ebrahimi   Emit(0x6518a000 | size | Rd(zd) | PgLow8(pg) | Rn(zn));
7047*f5c631daSSadaf Ebrahimi }
7048*f5c631daSSadaf Ebrahimi 
fmaxnmp(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)7049*f5c631daSSadaf Ebrahimi void Assembler::fmaxnmp(const ZRegister& zd,
7050*f5c631daSSadaf Ebrahimi                         const PRegisterM& pg,
7051*f5c631daSSadaf Ebrahimi                         const ZRegister& zn,
7052*f5c631daSSadaf Ebrahimi                         const ZRegister& zm) {
7053*f5c631daSSadaf Ebrahimi   // FMAXNMP <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
7054*f5c631daSSadaf Ebrahimi   //  0110 0100 ..01 0100 100. .... .... ....
7055*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> | Pg<12:10> | Zm<9:5> | Zdn<4:0>
7056*f5c631daSSadaf Ebrahimi 
7057*f5c631daSSadaf Ebrahimi   USE(zn);
7058*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7059*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
7060*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
7061*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
7062*f5c631daSSadaf Ebrahimi 
7063*f5c631daSSadaf Ebrahimi   Emit(0x64148000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
7064*f5c631daSSadaf Ebrahimi }
7065*f5c631daSSadaf Ebrahimi 
fmaxp(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)7066*f5c631daSSadaf Ebrahimi void Assembler::fmaxp(const ZRegister& zd,
7067*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
7068*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
7069*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
7070*f5c631daSSadaf Ebrahimi   // FMAXP <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
7071*f5c631daSSadaf Ebrahimi   //  0110 0100 ..01 0110 100. .... .... ....
7072*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> | Pg<12:10> | Zm<9:5> | Zdn<4:0>
7073*f5c631daSSadaf Ebrahimi 
7074*f5c631daSSadaf Ebrahimi   USE(zn);
7075*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7076*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
7077*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
7078*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
7079*f5c631daSSadaf Ebrahimi 
7080*f5c631daSSadaf Ebrahimi   Emit(0x64168000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
7081*f5c631daSSadaf Ebrahimi }
7082*f5c631daSSadaf Ebrahimi 
fminnmp(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)7083*f5c631daSSadaf Ebrahimi void Assembler::fminnmp(const ZRegister& zd,
7084*f5c631daSSadaf Ebrahimi                         const PRegisterM& pg,
7085*f5c631daSSadaf Ebrahimi                         const ZRegister& zn,
7086*f5c631daSSadaf Ebrahimi                         const ZRegister& zm) {
7087*f5c631daSSadaf Ebrahimi   // FMINNMP <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
7088*f5c631daSSadaf Ebrahimi   //  0110 0100 ..01 0101 100. .... .... ....
7089*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> | Pg<12:10> | Zm<9:5> | Zdn<4:0>
7090*f5c631daSSadaf Ebrahimi 
7091*f5c631daSSadaf Ebrahimi   USE(zn);
7092*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7093*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
7094*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
7095*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
7096*f5c631daSSadaf Ebrahimi 
7097*f5c631daSSadaf Ebrahimi   Emit(0x64158000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
7098*f5c631daSSadaf Ebrahimi }
7099*f5c631daSSadaf Ebrahimi 
fminp(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)7100*f5c631daSSadaf Ebrahimi void Assembler::fminp(const ZRegister& zd,
7101*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
7102*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
7103*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
7104*f5c631daSSadaf Ebrahimi   // FMINP <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
7105*f5c631daSSadaf Ebrahimi   //  0110 0100 ..01 0111 100. .... .... ....
7106*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:16> | Pg<12:10> | Zm<9:5> | Zdn<4:0>
7107*f5c631daSSadaf Ebrahimi 
7108*f5c631daSSadaf Ebrahimi   USE(zn);
7109*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7110*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
7111*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
7112*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
7113*f5c631daSSadaf Ebrahimi 
7114*f5c631daSSadaf Ebrahimi   Emit(0x64178000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
7115*f5c631daSSadaf Ebrahimi }
7116*f5c631daSSadaf Ebrahimi 
fmlalb(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)7117*f5c631daSSadaf Ebrahimi void Assembler::fmlalb(const ZRegister& zda,
7118*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
7119*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
7120*f5c631daSSadaf Ebrahimi   // FMLALB <Zda>.S, <Zn>.H, <Zm>.H
7121*f5c631daSSadaf Ebrahimi   //  0110 0100 101. .... 1000 00.. .... ....
7122*f5c631daSSadaf Ebrahimi   //  o2<22> | Zm<20:16> | op<13> | T<10> | Zn<9:5> | Zda<4:0>
7123*f5c631daSSadaf Ebrahimi 
7124*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7125*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.IsLaneSizeS());
7126*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.IsLaneSizeH() && zm.IsLaneSizeH());
7127*f5c631daSSadaf Ebrahimi 
7128*f5c631daSSadaf Ebrahimi   Emit(0x64a08000 | Rd(zda) | Rn(zn) | Rm(zm));
7129*f5c631daSSadaf Ebrahimi }
7130*f5c631daSSadaf Ebrahimi 
fmlalb(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm,int index)7131*f5c631daSSadaf Ebrahimi void Assembler::fmlalb(const ZRegister& zda,
7132*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
7133*f5c631daSSadaf Ebrahimi                        const ZRegister& zm,
7134*f5c631daSSadaf Ebrahimi                        int index) {
7135*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7136*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.IsLaneSizeS());
7137*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.IsLaneSizeH() && zm.IsLaneSizeH());
7138*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((zm.GetCode() <= 7) && (index <= 7));
7139*f5c631daSSadaf Ebrahimi   Instr zm_and_idx = (ExtractUnsignedBitfield32(2, 1, index) << 19) |
7140*f5c631daSSadaf Ebrahimi                      (ExtractBit(index, 0) << 11) | Rx<18, 16>(zm);
7141*f5c631daSSadaf Ebrahimi 
7142*f5c631daSSadaf Ebrahimi   Emit(0x64a04000 | Rd(zda) | Rn(zn) | zm_and_idx);
7143*f5c631daSSadaf Ebrahimi }
7144*f5c631daSSadaf Ebrahimi 
fmlalt(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)7145*f5c631daSSadaf Ebrahimi void Assembler::fmlalt(const ZRegister& zda,
7146*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
7147*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
7148*f5c631daSSadaf Ebrahimi   // FMLALT <Zda>.S, <Zn>.H, <Zm>.H
7149*f5c631daSSadaf Ebrahimi   //  0110 0100 101. .... 1000 01.. .... ....
7150*f5c631daSSadaf Ebrahimi   //  o2<22> | Zm<20:16> | op<13> | T<10> | Zn<9:5> | Zda<4:0>
7151*f5c631daSSadaf Ebrahimi 
7152*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7153*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.IsLaneSizeS());
7154*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.IsLaneSizeH() && zm.IsLaneSizeH());
7155*f5c631daSSadaf Ebrahimi 
7156*f5c631daSSadaf Ebrahimi   Emit(0x64a08400 | Rd(zda) | Rn(zn) | Rm(zm));
7157*f5c631daSSadaf Ebrahimi }
7158*f5c631daSSadaf Ebrahimi 
fmlalt(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm,int index)7159*f5c631daSSadaf Ebrahimi void Assembler::fmlalt(const ZRegister& zda,
7160*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
7161*f5c631daSSadaf Ebrahimi                        const ZRegister& zm,
7162*f5c631daSSadaf Ebrahimi                        int index) {
7163*f5c631daSSadaf Ebrahimi   // FMLALT <Zda>.S, <Zn>.H, <Zm>.H
7164*f5c631daSSadaf Ebrahimi   //  0110 0100 101. .... 1000 01.. .... ....
7165*f5c631daSSadaf Ebrahimi   //  o2<22> | Zm<20:16> | op<13> | T<10> | Zn<9:5> | Zda<4:0>
7166*f5c631daSSadaf Ebrahimi 
7167*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7168*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.IsLaneSizeS());
7169*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.IsLaneSizeH() && zm.IsLaneSizeH());
7170*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((zm.GetCode() <= 7) && (index <= 7));
7171*f5c631daSSadaf Ebrahimi   Instr zm_and_idx = (ExtractUnsignedBitfield32(2, 1, index) << 19) |
7172*f5c631daSSadaf Ebrahimi                      (ExtractBit(index, 0) << 11) | Rx<18, 16>(zm);
7173*f5c631daSSadaf Ebrahimi 
7174*f5c631daSSadaf Ebrahimi   Emit(0x64a04400 | Rd(zda) | Rn(zn) | zm_and_idx);
7175*f5c631daSSadaf Ebrahimi }
7176*f5c631daSSadaf Ebrahimi 
fmlslb(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)7177*f5c631daSSadaf Ebrahimi void Assembler::fmlslb(const ZRegister& zda,
7178*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
7179*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
7180*f5c631daSSadaf Ebrahimi   // FMLSLB <Zda>.S, <Zn>.H, <Zm>.H
7181*f5c631daSSadaf Ebrahimi   //  0110 0100 101. .... 1010 00.. .... ....
7182*f5c631daSSadaf Ebrahimi   //  o2<22> | Zm<20:16> | op<13> | T<10> | Zn<9:5> | Zda<4:0>
7183*f5c631daSSadaf Ebrahimi 
7184*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7185*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.IsLaneSizeS());
7186*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.IsLaneSizeH() && zm.IsLaneSizeH());
7187*f5c631daSSadaf Ebrahimi 
7188*f5c631daSSadaf Ebrahimi   Emit(0x64a0a000 | Rd(zda) | Rn(zn) | Rm(zm));
7189*f5c631daSSadaf Ebrahimi }
7190*f5c631daSSadaf Ebrahimi 
fmlslb(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm,int index)7191*f5c631daSSadaf Ebrahimi void Assembler::fmlslb(const ZRegister& zda,
7192*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
7193*f5c631daSSadaf Ebrahimi                        const ZRegister& zm,
7194*f5c631daSSadaf Ebrahimi                        int index) {
7195*f5c631daSSadaf Ebrahimi   // FMLSLB <Zda>.S, <Zn>.H, <Zm>.H
7196*f5c631daSSadaf Ebrahimi   //  0110 0100 101. .... 1010 00.. .... ....
7197*f5c631daSSadaf Ebrahimi   //  o2<22> | Zm<20:16> | op<13> | T<10> | Zn<9:5> | Zda<4:0>
7198*f5c631daSSadaf Ebrahimi 
7199*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7200*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.IsLaneSizeS());
7201*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.IsLaneSizeH() && zm.IsLaneSizeH());
7202*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((zm.GetCode() <= 7) && (index <= 7));
7203*f5c631daSSadaf Ebrahimi   Instr zm_and_idx = (ExtractUnsignedBitfield32(2, 1, index) << 19) |
7204*f5c631daSSadaf Ebrahimi                      (ExtractBit(index, 0) << 11) | Rx<18, 16>(zm);
7205*f5c631daSSadaf Ebrahimi 
7206*f5c631daSSadaf Ebrahimi   Emit(0x64a06000 | Rd(zda) | Rn(zn) | zm_and_idx);
7207*f5c631daSSadaf Ebrahimi }
7208*f5c631daSSadaf Ebrahimi 
fmlslt(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)7209*f5c631daSSadaf Ebrahimi void Assembler::fmlslt(const ZRegister& zda,
7210*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
7211*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
7212*f5c631daSSadaf Ebrahimi   // FMLSLT <Zda>.S, <Zn>.H, <Zm>.H
7213*f5c631daSSadaf Ebrahimi   //  0110 0100 101. .... 1010 01.. .... ....
7214*f5c631daSSadaf Ebrahimi   //  o2<22> | Zm<20:16> | op<13> | T<10> | Zn<9:5> | Zda<4:0>
7215*f5c631daSSadaf Ebrahimi 
7216*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7217*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.IsLaneSizeS());
7218*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.IsLaneSizeH() && zm.IsLaneSizeH());
7219*f5c631daSSadaf Ebrahimi 
7220*f5c631daSSadaf Ebrahimi   Emit(0x64a0a400 | Rd(zda) | Rn(zn) | Rm(zm));
7221*f5c631daSSadaf Ebrahimi }
7222*f5c631daSSadaf Ebrahimi 
fmlslt(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm,int index)7223*f5c631daSSadaf Ebrahimi void Assembler::fmlslt(const ZRegister& zda,
7224*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
7225*f5c631daSSadaf Ebrahimi                        const ZRegister& zm,
7226*f5c631daSSadaf Ebrahimi                        int index) {
7227*f5c631daSSadaf Ebrahimi   // FMLSLT <Zda>.S, <Zn>.H, <Zm>.H
7228*f5c631daSSadaf Ebrahimi   //  0110 0100 101. .... 1010 01.. .... ....
7229*f5c631daSSadaf Ebrahimi   //  o2<22> | Zm<20:16> | op<13> | T<10> | Zn<9:5> | Zda<4:0>
7230*f5c631daSSadaf Ebrahimi 
7231*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7232*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.IsLaneSizeS());
7233*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.IsLaneSizeH() && zm.IsLaneSizeH());
7234*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((zm.GetCode() <= 7) && (index <= 7));
7235*f5c631daSSadaf Ebrahimi   Instr zm_and_idx = (ExtractUnsignedBitfield32(2, 1, index) << 19) |
7236*f5c631daSSadaf Ebrahimi                      (ExtractBit(index, 0) << 11) | Rx<18, 16>(zm);
7237*f5c631daSSadaf Ebrahimi 
7238*f5c631daSSadaf Ebrahimi   Emit(0x64a06400 | Rd(zda) | Rn(zn) | zm_and_idx);
7239*f5c631daSSadaf Ebrahimi }
7240*f5c631daSSadaf Ebrahimi 
histcnt(const ZRegister & zd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)7241*f5c631daSSadaf Ebrahimi void Assembler::histcnt(const ZRegister& zd,
7242*f5c631daSSadaf Ebrahimi                         const PRegisterZ& pg,
7243*f5c631daSSadaf Ebrahimi                         const ZRegister& zn,
7244*f5c631daSSadaf Ebrahimi                         const ZRegister& zm) {
7245*f5c631daSSadaf Ebrahimi   // HISTCNT <Zd>.<T>, <Pg>/Z, <Zn>.<T>, <Zm>.<T>
7246*f5c631daSSadaf Ebrahimi   //  0100 0101 ..1. .... 110. .... .... ....
7247*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | Pg<12:10> | Zn<9:5> | Zd<4:0>
7248*f5c631daSSadaf Ebrahimi 
7249*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7250*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
7251*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeS() || zd.IsLaneSizeD());
7252*f5c631daSSadaf Ebrahimi 
7253*f5c631daSSadaf Ebrahimi   Emit(0x4520c000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn) | Rm(zm));
7254*f5c631daSSadaf Ebrahimi }
7255*f5c631daSSadaf Ebrahimi 
histseg(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7256*f5c631daSSadaf Ebrahimi void Assembler::histseg(const ZRegister& zd,
7257*f5c631daSSadaf Ebrahimi                         const ZRegister& zn,
7258*f5c631daSSadaf Ebrahimi                         const ZRegister& zm) {
7259*f5c631daSSadaf Ebrahimi   // HISTSEG <Zd>.B, <Zn>.B, <Zm>.B
7260*f5c631daSSadaf Ebrahimi   //  0100 0101 ..1. .... 1010 00.. .... ....
7261*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | Zn<9:5> | Zd<4:0>
7262*f5c631daSSadaf Ebrahimi 
7263*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7264*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
7265*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeB());
7266*f5c631daSSadaf Ebrahimi 
7267*f5c631daSSadaf Ebrahimi   Emit(0x4520a000 | Rd(zd) | Rn(zn) | Rm(zm));
7268*f5c631daSSadaf Ebrahimi }
7269*f5c631daSSadaf Ebrahimi 
match(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)7270*f5c631daSSadaf Ebrahimi void Assembler::match(const PRegisterWithLaneSize& pd,
7271*f5c631daSSadaf Ebrahimi                       const PRegisterZ& pg,
7272*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
7273*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
7274*f5c631daSSadaf Ebrahimi   // MATCH <Pd>.<T>, <Pg>/Z, <Zn>.<T>, <Zm>.<T>
7275*f5c631daSSadaf Ebrahimi   //  0100 0101 ..1. .... 100. .... ...0 ....
7276*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | Pg<12:10> | Zn<9:5> | op<4> | Pd<3:0>
7277*f5c631daSSadaf Ebrahimi 
7278*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7279*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, zn, zm));
7280*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zm.IsLaneSizeB() || zm.IsLaneSizeH());
7281*f5c631daSSadaf Ebrahimi 
7282*f5c631daSSadaf Ebrahimi   Emit(0x45208000 | SVESize(zm) | Pd(pd) | PgLow8(pg) | Rn(zn) | Rm(zm));
7283*f5c631daSSadaf Ebrahimi }
7284*f5c631daSSadaf Ebrahimi 
mla(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm,int index)7285*f5c631daSSadaf Ebrahimi void Assembler::mla(const ZRegister& zda,
7286*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
7287*f5c631daSSadaf Ebrahimi                     const ZRegister& zm,
7288*f5c631daSSadaf Ebrahimi                     int index) {
7289*f5c631daSSadaf Ebrahimi   // MLA <Zda>.D, <Zn>.D, <Zm>.D[<imm>]
7290*f5c631daSSadaf Ebrahimi   //  0100 0100 111. .... 0000 10.. .... ....
7291*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<20:16> | S<10> | Zn<9:5> | Zda<4:0>
7292*f5c631daSSadaf Ebrahimi 
7293*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7294*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn, zm));
7295*f5c631daSSadaf Ebrahimi 
7296*f5c631daSSadaf Ebrahimi   Instr synthesised_op = SVEMulIndexHelper(zda.GetLaneSizeInBytesLog2(),
7297*f5c631daSSadaf Ebrahimi                                            zm,
7298*f5c631daSSadaf Ebrahimi                                            index,
7299*f5c631daSSadaf Ebrahimi                                            0x44200800,
7300*f5c631daSSadaf Ebrahimi                                            0x44a00800,
7301*f5c631daSSadaf Ebrahimi                                            0x44e00800);
7302*f5c631daSSadaf Ebrahimi 
7303*f5c631daSSadaf Ebrahimi   Emit(synthesised_op | Rd(zda) | Rn(zn));
7304*f5c631daSSadaf Ebrahimi }
7305*f5c631daSSadaf Ebrahimi 
mls(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm,int index)7306*f5c631daSSadaf Ebrahimi void Assembler::mls(const ZRegister& zda,
7307*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
7308*f5c631daSSadaf Ebrahimi                     const ZRegister& zm,
7309*f5c631daSSadaf Ebrahimi                     int index) {
7310*f5c631daSSadaf Ebrahimi   // MLS <Zda>.D, <Zn>.D, <Zm>.D[<imm>]
7311*f5c631daSSadaf Ebrahimi   //  0100 0100 111. .... 0000 11.. .... ....
7312*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<20:16> | S<10> | Zn<9:5> | Zda<4:0>
7313*f5c631daSSadaf Ebrahimi 
7314*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7315*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn, zm));
7316*f5c631daSSadaf Ebrahimi 
7317*f5c631daSSadaf Ebrahimi   Instr synthesised_op = SVEMulIndexHelper(zda.GetLaneSizeInBytesLog2(),
7318*f5c631daSSadaf Ebrahimi                                            zm,
7319*f5c631daSSadaf Ebrahimi                                            index,
7320*f5c631daSSadaf Ebrahimi                                            0x44200c00,
7321*f5c631daSSadaf Ebrahimi                                            0x44a00c00,
7322*f5c631daSSadaf Ebrahimi                                            0x44e00c00);
7323*f5c631daSSadaf Ebrahimi 
7324*f5c631daSSadaf Ebrahimi   Emit(synthesised_op | Rd(zda) | Rn(zn));
7325*f5c631daSSadaf Ebrahimi }
7326*f5c631daSSadaf Ebrahimi 
mul(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm,int index)7327*f5c631daSSadaf Ebrahimi void Assembler::mul(const ZRegister& zd,
7328*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
7329*f5c631daSSadaf Ebrahimi                     const ZRegister& zm,
7330*f5c631daSSadaf Ebrahimi                     int index) {
7331*f5c631daSSadaf Ebrahimi   // MUL <Zd>.D, <Zn>.D, <Zm>.D[<imm>]
7332*f5c631daSSadaf Ebrahimi   //  0100 0100 111. .... 1111 10.. .... ....
7333*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<20:16> | Zn<9:5> | Zd<4:0>
7334*f5c631daSSadaf Ebrahimi 
7335*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7336*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
7337*f5c631daSSadaf Ebrahimi 
7338*f5c631daSSadaf Ebrahimi   Instr synthesised_op = SVEMulIndexHelper(zd.GetLaneSizeInBytesLog2(),
7339*f5c631daSSadaf Ebrahimi                                            zm,
7340*f5c631daSSadaf Ebrahimi                                            index,
7341*f5c631daSSadaf Ebrahimi                                            0x4420f800,
7342*f5c631daSSadaf Ebrahimi                                            0x44a0f800,
7343*f5c631daSSadaf Ebrahimi                                            0x44e0f800);
7344*f5c631daSSadaf Ebrahimi 
7345*f5c631daSSadaf Ebrahimi   Emit(synthesised_op | Rd(zd) | Rn(zn));
7346*f5c631daSSadaf Ebrahimi }
7347*f5c631daSSadaf Ebrahimi 
mul(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7348*f5c631daSSadaf Ebrahimi void Assembler::mul(const ZRegister& zd,
7349*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
7350*f5c631daSSadaf Ebrahimi                     const ZRegister& zm) {
7351*f5c631daSSadaf Ebrahimi   // MUL <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
7352*f5c631daSSadaf Ebrahimi   //  0000 0100 ..1. .... 0110 00.. .... ....
7353*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<11:10> | Zn<9:5> | Zd<4:0>
7354*f5c631daSSadaf Ebrahimi 
7355*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7356*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
7357*f5c631daSSadaf Ebrahimi 
7358*f5c631daSSadaf Ebrahimi   Emit(0x04206000 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
7359*f5c631daSSadaf Ebrahimi }
7360*f5c631daSSadaf Ebrahimi 
nbsl(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm,const ZRegister & zk)7361*f5c631daSSadaf Ebrahimi void Assembler::nbsl(const ZRegister& zd,
7362*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
7363*f5c631daSSadaf Ebrahimi                      const ZRegister& zm,
7364*f5c631daSSadaf Ebrahimi                      const ZRegister& zk) {
7365*f5c631daSSadaf Ebrahimi   // NBSL <Zdn>.D, <Zdn>.D, <Zm>.D, <Zk>.D
7366*f5c631daSSadaf Ebrahimi   //  0000 0100 111. .... 0011 11.. .... ....
7367*f5c631daSSadaf Ebrahimi   //  opc<23:22> | Zm<20:16> | o2<10> | Zk<9:5> | Zdn<4:0>
7368*f5c631daSSadaf Ebrahimi 
7369*f5c631daSSadaf Ebrahimi   USE(zn);
7370*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7371*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
7372*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm, zk));
7373*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeD());
7374*f5c631daSSadaf Ebrahimi 
7375*f5c631daSSadaf Ebrahimi   Emit(0x04e03c00 | Rd(zd) | Rm(zm) | Rn(zk));
7376*f5c631daSSadaf Ebrahimi }
7377*f5c631daSSadaf Ebrahimi 
nmatch(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)7378*f5c631daSSadaf Ebrahimi void Assembler::nmatch(const PRegisterWithLaneSize& pd,
7379*f5c631daSSadaf Ebrahimi                        const PRegisterZ& pg,
7380*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
7381*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
7382*f5c631daSSadaf Ebrahimi   // NMATCH <Pd>.<T>, <Pg>/Z, <Zn>.<T>, <Zm>.<T>
7383*f5c631daSSadaf Ebrahimi   //  0100 0101 ..1. .... 100. .... ...1 ....
7384*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | Pg<12:10> | Zn<9:5> | op<4> | Pd<3:0>
7385*f5c631daSSadaf Ebrahimi 
7386*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7387*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(pd, zn, zm));
7388*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zm.IsLaneSizeB() || zm.IsLaneSizeH());
7389*f5c631daSSadaf Ebrahimi 
7390*f5c631daSSadaf Ebrahimi   Emit(0x45208010 | SVESize(zm) | Pd(pd) | PgLow8(pg) | Rn(zn) | Rm(zm));
7391*f5c631daSSadaf Ebrahimi }
7392*f5c631daSSadaf Ebrahimi 
pmul(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7393*f5c631daSSadaf Ebrahimi void Assembler::pmul(const ZRegister& zd,
7394*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
7395*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
7396*f5c631daSSadaf Ebrahimi   // PMUL <Zd>.B, <Zn>.B, <Zm>.B
7397*f5c631daSSadaf Ebrahimi   //  0000 0100 001. .... 0110 01.. .... ....
7398*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<11:10> | Zn<9:5> | Zd<4:0>
7399*f5c631daSSadaf Ebrahimi 
7400*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7401*f5c631daSSadaf Ebrahimi 
7402*f5c631daSSadaf Ebrahimi   Emit(0x04206400 | Rd(zd) | Rn(zn) | Rm(zm));
7403*f5c631daSSadaf Ebrahimi }
7404*f5c631daSSadaf Ebrahimi 
pmullb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7405*f5c631daSSadaf Ebrahimi void Assembler::pmullb(const ZRegister& zd,
7406*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
7407*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
7408*f5c631daSSadaf Ebrahimi   // PMULLB <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
7409*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 0110 10.. .... ....
7410*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<12> | U<11> | T<10> | Zn<9:5> | Zd<4:0>
7411*f5c631daSSadaf Ebrahimi 
7412*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7413*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
7414*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zd.IsLaneSizeB() && !zd.IsLaneSizeS());
7415*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == zn.GetLaneSizeInBytes() * 2);
7416*f5c631daSSadaf Ebrahimi   // SVEPmull128 is not supported
7417*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zd.IsLaneSizeQ());
7418*f5c631daSSadaf Ebrahimi 
7419*f5c631daSSadaf Ebrahimi   Emit(0x45006800 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
7420*f5c631daSSadaf Ebrahimi }
7421*f5c631daSSadaf Ebrahimi 
pmullt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7422*f5c631daSSadaf Ebrahimi void Assembler::pmullt(const ZRegister& zd,
7423*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
7424*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
7425*f5c631daSSadaf Ebrahimi   // PMULLT <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
7426*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 0110 11.. .... ....
7427*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<12> | U<11> | T<10> | Zn<9:5> | Zd<4:0>
7428*f5c631daSSadaf Ebrahimi 
7429*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7430*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
7431*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zd.IsLaneSizeB() && !zd.IsLaneSizeS());
7432*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == zn.GetLaneSizeInBytes() * 2);
7433*f5c631daSSadaf Ebrahimi   // SVEPmull128 is not supported
7434*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zd.IsLaneSizeQ());
7435*f5c631daSSadaf Ebrahimi 
7436*f5c631daSSadaf Ebrahimi   Emit(0x45006c00 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
7437*f5c631daSSadaf Ebrahimi }
7438*f5c631daSSadaf Ebrahimi 
raddhnb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7439*f5c631daSSadaf Ebrahimi void Assembler::raddhnb(const ZRegister& zd,
7440*f5c631daSSadaf Ebrahimi                         const ZRegister& zn,
7441*f5c631daSSadaf Ebrahimi                         const ZRegister& zm) {
7442*f5c631daSSadaf Ebrahimi   // RADDHNB <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
7443*f5c631daSSadaf Ebrahimi   //  0100 0101 ..1. .... 0110 10.. .... ....
7444*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<12> | R<11> | T<10> | Zn<9:5> | Zd<4:0>
7445*f5c631daSSadaf Ebrahimi 
7446*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7447*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
7448*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() == (zd.GetLaneSizeInBytes() * 2));
7449*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() != kBRegSizeInBytes);
7450*f5c631daSSadaf Ebrahimi 
7451*f5c631daSSadaf Ebrahimi   Emit(0x45206800 | SVESize(zn) | Rd(zd) | Rn(zn) | Rm(zm));
7452*f5c631daSSadaf Ebrahimi }
7453*f5c631daSSadaf Ebrahimi 
raddhnt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7454*f5c631daSSadaf Ebrahimi void Assembler::raddhnt(const ZRegister& zd,
7455*f5c631daSSadaf Ebrahimi                         const ZRegister& zn,
7456*f5c631daSSadaf Ebrahimi                         const ZRegister& zm) {
7457*f5c631daSSadaf Ebrahimi   // RADDHNT <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
7458*f5c631daSSadaf Ebrahimi   //  0100 0101 ..1. .... 0110 11.. .... ....
7459*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<12> | R<11> | T<10> | Zn<9:5> | Zd<4:0>
7460*f5c631daSSadaf Ebrahimi 
7461*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7462*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
7463*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() == (zd.GetLaneSizeInBytes() * 2));
7464*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() != kBRegSizeInBytes);
7465*f5c631daSSadaf Ebrahimi 
7466*f5c631daSSadaf Ebrahimi   Emit(0x45206c00 | SVESize(zn) | Rd(zd) | Rn(zn) | Rm(zm));
7467*f5c631daSSadaf Ebrahimi }
7468*f5c631daSSadaf Ebrahimi 
7469*f5c631daSSadaf Ebrahimi #define VIXL_SVE_SHR_LIST(V) \
7470*f5c631daSSadaf Ebrahimi   V(rshrnb, 0x45201800)      \
7471*f5c631daSSadaf Ebrahimi   V(rshrnt, 0x45201c00)      \
7472*f5c631daSSadaf Ebrahimi   V(shrnb, 0x45201000)       \
7473*f5c631daSSadaf Ebrahimi   V(shrnt, 0x45201400)       \
7474*f5c631daSSadaf Ebrahimi   V(sqrshrnb, 0x45202800)    \
7475*f5c631daSSadaf Ebrahimi   V(sqrshrnt, 0x45202c00)    \
7476*f5c631daSSadaf Ebrahimi   V(sqrshrunb, 0x45200800)   \
7477*f5c631daSSadaf Ebrahimi   V(sqrshrunt, 0x45200c00)   \
7478*f5c631daSSadaf Ebrahimi   V(sqshrnb, 0x45202000)     \
7479*f5c631daSSadaf Ebrahimi   V(sqshrnt, 0x45202400)     \
7480*f5c631daSSadaf Ebrahimi   V(sqshrunb, 0x45200000)    \
7481*f5c631daSSadaf Ebrahimi   V(sqshrunt, 0x45200400)    \
7482*f5c631daSSadaf Ebrahimi   V(uqrshrnb, 0x45203800)    \
7483*f5c631daSSadaf Ebrahimi   V(uqrshrnt, 0x45203c00)    \
7484*f5c631daSSadaf Ebrahimi   V(uqshrnb, 0x45203000)     \
7485*f5c631daSSadaf Ebrahimi   V(uqshrnt, 0x45203400)
7486*f5c631daSSadaf Ebrahimi 
7487*f5c631daSSadaf Ebrahimi #define VIXL_DEFINE_ASM_FUNC(MNE, X)                                         \
7488*f5c631daSSadaf Ebrahimi   void Assembler::MNE(const ZRegister& zd, const ZRegister& zn, int shift) { \
7489*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));                                 \
7490*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(!zd.IsLaneSizeD() && !zd.IsLaneSizeQ());                     \
7491*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zn.GetLaneSizeInBytes() == (zd.GetLaneSizeInBytes() * 2));   \
7492*f5c631daSSadaf Ebrahimi     Instr encoded_imm =                                                      \
7493*f5c631daSSadaf Ebrahimi         EncodeSVEShiftRightImmediate(shift, zd.GetLaneSizeInBits());         \
7494*f5c631daSSadaf Ebrahimi     SVEBitwiseShiftImmediate(zd, zn, encoded_imm, X);                        \
7495*f5c631daSSadaf Ebrahimi   }
VIXL_SVE_SHR_LIST(VIXL_DEFINE_ASM_FUNC)7496*f5c631daSSadaf Ebrahimi VIXL_SVE_SHR_LIST(VIXL_DEFINE_ASM_FUNC)
7497*f5c631daSSadaf Ebrahimi #undef VIXL_DEFINE_ASM_FUNC
7498*f5c631daSSadaf Ebrahimi 
7499*f5c631daSSadaf Ebrahimi void Assembler::rsubhnb(const ZRegister& zd,
7500*f5c631daSSadaf Ebrahimi                         const ZRegister& zn,
7501*f5c631daSSadaf Ebrahimi                         const ZRegister& zm) {
7502*f5c631daSSadaf Ebrahimi   // RSUBHNB <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
7503*f5c631daSSadaf Ebrahimi   //  0100 0101 ..1. .... 0111 10.. .... ....
7504*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<12> | R<11> | T<10> | Zn<9:5> | Zd<4:0>
7505*f5c631daSSadaf Ebrahimi 
7506*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7507*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
7508*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() == (zd.GetLaneSizeInBytes() * 2));
7509*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() != kBRegSizeInBytes);
7510*f5c631daSSadaf Ebrahimi 
7511*f5c631daSSadaf Ebrahimi   Emit(0x45207800 | SVESize(zn) | Rd(zd) | Rn(zn) | Rm(zm));
7512*f5c631daSSadaf Ebrahimi }
7513*f5c631daSSadaf Ebrahimi 
rsubhnt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7514*f5c631daSSadaf Ebrahimi void Assembler::rsubhnt(const ZRegister& zd,
7515*f5c631daSSadaf Ebrahimi                         const ZRegister& zn,
7516*f5c631daSSadaf Ebrahimi                         const ZRegister& zm) {
7517*f5c631daSSadaf Ebrahimi   // RSUBHNT <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
7518*f5c631daSSadaf Ebrahimi   //  0100 0101 ..1. .... 0111 11.. .... ....
7519*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<12> | R<11> | T<10> | Zn<9:5> | Zd<4:0>
7520*f5c631daSSadaf Ebrahimi 
7521*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7522*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
7523*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() == (zd.GetLaneSizeInBytes() * 2));
7524*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() != kBRegSizeInBytes);
7525*f5c631daSSadaf Ebrahimi 
7526*f5c631daSSadaf Ebrahimi   Emit(0x45207c00 | SVESize(zn) | Rd(zd) | Rn(zn) | Rm(zm));
7527*f5c631daSSadaf Ebrahimi }
7528*f5c631daSSadaf Ebrahimi 
saba(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)7529*f5c631daSSadaf Ebrahimi void Assembler::saba(const ZRegister& zda,
7530*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
7531*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
7532*f5c631daSSadaf Ebrahimi   // SABA <Zda>.<T>, <Zn>.<T>, <Zm>.<T>
7533*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 1111 10.. .... ....
7534*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | U<10> | Zn<9:5> | Zda<4:0>
7535*f5c631daSSadaf Ebrahimi 
7536*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7537*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn, zm));
7538*f5c631daSSadaf Ebrahimi 
7539*f5c631daSSadaf Ebrahimi   Emit(0x4500f800 | SVESize(zda) | Rd(zda) | Rn(zn) | Rm(zm));
7540*f5c631daSSadaf Ebrahimi }
7541*f5c631daSSadaf Ebrahimi 
sabalb(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)7542*f5c631daSSadaf Ebrahimi void Assembler::sabalb(const ZRegister& zda,
7543*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
7544*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
7545*f5c631daSSadaf Ebrahimi   // SABALB <Zda>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
7546*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 1100 00.. .... ....
7547*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | U<11> | T<10> | Zn<9:5> | Zda<4:0>
7548*f5c631daSSadaf Ebrahimi 
7549*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7550*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
7551*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
7552*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() != kBRegSizeInBytes);
7553*f5c631daSSadaf Ebrahimi 
7554*f5c631daSSadaf Ebrahimi   Emit(0x4500c000 | SVESize(zda) | Rd(zda) | Rn(zn) | Rm(zm));
7555*f5c631daSSadaf Ebrahimi }
7556*f5c631daSSadaf Ebrahimi 
sabalt(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)7557*f5c631daSSadaf Ebrahimi void Assembler::sabalt(const ZRegister& zda,
7558*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
7559*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
7560*f5c631daSSadaf Ebrahimi   // SABALT <Zda>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
7561*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 1100 01.. .... ....
7562*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | U<11> | T<10> | Zn<9:5> | Zda<4:0>
7563*f5c631daSSadaf Ebrahimi 
7564*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7565*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
7566*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
7567*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() != kBRegSizeInBytes);
7568*f5c631daSSadaf Ebrahimi 
7569*f5c631daSSadaf Ebrahimi   Emit(0x4500c400 | SVESize(zda) | Rd(zda) | Rn(zn) | Rm(zm));
7570*f5c631daSSadaf Ebrahimi }
7571*f5c631daSSadaf Ebrahimi 
sabdlb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7572*f5c631daSSadaf Ebrahimi void Assembler::sabdlb(const ZRegister& zd,
7573*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
7574*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
7575*f5c631daSSadaf Ebrahimi   // SABDLB <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
7576*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 0011 00.. .... ....
7577*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<13> | S<12> | U<11> | T<10> | Zn<9:5> |
7578*f5c631daSSadaf Ebrahimi   //  Zd<4:0>
7579*f5c631daSSadaf Ebrahimi 
7580*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7581*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
7582*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
7583*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
7584*f5c631daSSadaf Ebrahimi 
7585*f5c631daSSadaf Ebrahimi   Emit(0x45003000 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
7586*f5c631daSSadaf Ebrahimi }
7587*f5c631daSSadaf Ebrahimi 
sabdlt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7588*f5c631daSSadaf Ebrahimi void Assembler::sabdlt(const ZRegister& zd,
7589*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
7590*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
7591*f5c631daSSadaf Ebrahimi   // SABDLT <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
7592*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 0011 01.. .... ....
7593*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<13> | S<12> | U<11> | T<10> | Zn<9:5> |
7594*f5c631daSSadaf Ebrahimi   //  Zd<4:0>
7595*f5c631daSSadaf Ebrahimi 
7596*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7597*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
7598*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
7599*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
7600*f5c631daSSadaf Ebrahimi 
7601*f5c631daSSadaf Ebrahimi   Emit(0x45003400 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
7602*f5c631daSSadaf Ebrahimi }
7603*f5c631daSSadaf Ebrahimi 
sadalp(const ZRegister & zda,const PRegisterM & pg,const ZRegister & zn)7604*f5c631daSSadaf Ebrahimi void Assembler::sadalp(const ZRegister& zda,
7605*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
7606*f5c631daSSadaf Ebrahimi                        const ZRegister& zn) {
7607*f5c631daSSadaf Ebrahimi   // SADALP <Zda>.<T>, <Pg>/M, <Zn>.<Tb>
7608*f5c631daSSadaf Ebrahimi   //  0100 0100 ..00 0100 101. .... .... ....
7609*f5c631daSSadaf Ebrahimi   //  size<23:22> | U<16> | Pg<12:10> | Zn<9:5> | Zda<4:0>
7610*f5c631daSSadaf Ebrahimi 
7611*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7612*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
7613*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() != kBRegSizeInBytes);
7614*f5c631daSSadaf Ebrahimi 
7615*f5c631daSSadaf Ebrahimi   Emit(0x4404a000 | SVESize(zda) | Rd(zda) | PgLow8(pg) | Rn(zn));
7616*f5c631daSSadaf Ebrahimi }
7617*f5c631daSSadaf Ebrahimi 
saddlb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7618*f5c631daSSadaf Ebrahimi void Assembler::saddlb(const ZRegister& zd,
7619*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
7620*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
7621*f5c631daSSadaf Ebrahimi   // SADDLB <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
7622*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 0000 00.. .... ....
7623*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<13> | S<12> | U<11> | T<10> | Zn<9:5> |
7624*f5c631daSSadaf Ebrahimi   //  Zd<4:0>
7625*f5c631daSSadaf Ebrahimi 
7626*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7627*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
7628*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
7629*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
7630*f5c631daSSadaf Ebrahimi 
7631*f5c631daSSadaf Ebrahimi   Emit(0x45000000 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
7632*f5c631daSSadaf Ebrahimi }
7633*f5c631daSSadaf Ebrahimi 
saddlbt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7634*f5c631daSSadaf Ebrahimi void Assembler::saddlbt(const ZRegister& zd,
7635*f5c631daSSadaf Ebrahimi                         const ZRegister& zn,
7636*f5c631daSSadaf Ebrahimi                         const ZRegister& zm) {
7637*f5c631daSSadaf Ebrahimi   // SADDLBT <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
7638*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 1000 00.. .... ....
7639*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<11> | tb<10> | Zn<9:5> | Zd<4:0>
7640*f5c631daSSadaf Ebrahimi 
7641*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7642*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
7643*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
7644*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeD() || zd.IsLaneSizeH() || zd.IsLaneSizeS());
7645*f5c631daSSadaf Ebrahimi 
7646*f5c631daSSadaf Ebrahimi   Emit(0x45008000 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
7647*f5c631daSSadaf Ebrahimi }
7648*f5c631daSSadaf Ebrahimi 
saddlt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7649*f5c631daSSadaf Ebrahimi void Assembler::saddlt(const ZRegister& zd,
7650*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
7651*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
7652*f5c631daSSadaf Ebrahimi   // SADDLT <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
7653*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 0000 01.. .... ....
7654*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<13> | S<12> | U<11> | T<10> | Zn<9:5> |
7655*f5c631daSSadaf Ebrahimi   //  Zd<4:0>
7656*f5c631daSSadaf Ebrahimi 
7657*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7658*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
7659*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
7660*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
7661*f5c631daSSadaf Ebrahimi 
7662*f5c631daSSadaf Ebrahimi   Emit(0x45000400 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
7663*f5c631daSSadaf Ebrahimi }
7664*f5c631daSSadaf Ebrahimi 
saddwb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7665*f5c631daSSadaf Ebrahimi void Assembler::saddwb(const ZRegister& zd,
7666*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
7667*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
7668*f5c631daSSadaf Ebrahimi   // SADDWB <Zd>.<T>, <Zn>.<T>, <Zm>.<Tb>
7669*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 0100 00.. .... ....
7670*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<12> | U<11> | T<10> | Zn<9:5> | Zd<4:0>
7671*f5c631daSSadaf Ebrahimi 
7672*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7673*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
7674*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zm.GetLaneSizeInBytes() * 2));
7675*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
7676*f5c631daSSadaf Ebrahimi 
7677*f5c631daSSadaf Ebrahimi   Emit(0x45004000 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
7678*f5c631daSSadaf Ebrahimi }
7679*f5c631daSSadaf Ebrahimi 
saddwt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7680*f5c631daSSadaf Ebrahimi void Assembler::saddwt(const ZRegister& zd,
7681*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
7682*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
7683*f5c631daSSadaf Ebrahimi   // SADDWT <Zd>.<T>, <Zn>.<T>, <Zm>.<Tb>
7684*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 0100 01.. .... ....
7685*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<12> | U<11> | T<10> | Zn<9:5> | Zd<4:0>
7686*f5c631daSSadaf Ebrahimi 
7687*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7688*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
7689*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zm.GetLaneSizeInBytes() * 2));
7690*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
7691*f5c631daSSadaf Ebrahimi 
7692*f5c631daSSadaf Ebrahimi   Emit(0x45004400 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
7693*f5c631daSSadaf Ebrahimi }
7694*f5c631daSSadaf Ebrahimi 
sbclb(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)7695*f5c631daSSadaf Ebrahimi void Assembler::sbclb(const ZRegister& zda,
7696*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
7697*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
7698*f5c631daSSadaf Ebrahimi   // SBCLB <Zda>.<T>, <Zn>.<T>, <Zm>.<T>
7699*f5c631daSSadaf Ebrahimi   //  0100 0101 1.0. .... 1101 00.. .... ....
7700*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | T<10> | Zn<9:5> | Zda<4:0>
7701*f5c631daSSadaf Ebrahimi 
7702*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7703*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn, zm));
7704*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.IsLaneSizeS() || zda.IsLaneSizeD());
7705*f5c631daSSadaf Ebrahimi 
7706*f5c631daSSadaf Ebrahimi   Instr sz = zda.IsLaneSizeD() ? (1 << 22) : 0;
7707*f5c631daSSadaf Ebrahimi   Emit(0x4580d000 | sz | Rd(zda) | Rn(zn) | Rm(zm));
7708*f5c631daSSadaf Ebrahimi }
7709*f5c631daSSadaf Ebrahimi 
sbclt(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)7710*f5c631daSSadaf Ebrahimi void Assembler::sbclt(const ZRegister& zda,
7711*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
7712*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
7713*f5c631daSSadaf Ebrahimi   // SBCLT <Zda>.<T>, <Zn>.<T>, <Zm>.<T>
7714*f5c631daSSadaf Ebrahimi   //  0100 0101 1.0. .... 1101 01.. .... ....
7715*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | T<10> | Zn<9:5> | Zda<4:0>
7716*f5c631daSSadaf Ebrahimi 
7717*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7718*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn, zm));
7719*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.IsLaneSizeS() || zda.IsLaneSizeD());
7720*f5c631daSSadaf Ebrahimi 
7721*f5c631daSSadaf Ebrahimi   Instr sz = zda.IsLaneSizeD() ? (1 << 22) : 0;
7722*f5c631daSSadaf Ebrahimi   Emit(0x4580d400 | sz | Rd(zda) | Rn(zn) | Rm(zm));
7723*f5c631daSSadaf Ebrahimi }
7724*f5c631daSSadaf Ebrahimi 
shadd(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)7725*f5c631daSSadaf Ebrahimi void Assembler::shadd(const ZRegister& zd,
7726*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
7727*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
7728*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
7729*f5c631daSSadaf Ebrahimi   // SHADD <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
7730*f5c631daSSadaf Ebrahimi   //  0100 0100 ..01 0000 100. .... .... ....
7731*f5c631daSSadaf Ebrahimi   //  size<23:22> | R<18> | S<17> | U<16> | Pg<12:10> | Zm<9:5> | Zdn<4:0>
7732*f5c631daSSadaf Ebrahimi 
7733*f5c631daSSadaf Ebrahimi   USE(zn);
7734*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7735*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
7736*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
7737*f5c631daSSadaf Ebrahimi 
7738*f5c631daSSadaf Ebrahimi   Emit(0x44108000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
7739*f5c631daSSadaf Ebrahimi }
7740*f5c631daSSadaf Ebrahimi 
shsub(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)7741*f5c631daSSadaf Ebrahimi void Assembler::shsub(const ZRegister& zd,
7742*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
7743*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
7744*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
7745*f5c631daSSadaf Ebrahimi   // SHSUB <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
7746*f5c631daSSadaf Ebrahimi   //  0100 0100 ..01 0010 100. .... .... ....
7747*f5c631daSSadaf Ebrahimi   //  size<23:22> | R<18> | S<17> | U<16> | Pg<12:10> | Zm<9:5> | Zdn<4:0>
7748*f5c631daSSadaf Ebrahimi 
7749*f5c631daSSadaf Ebrahimi   USE(zn);
7750*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7751*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
7752*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
7753*f5c631daSSadaf Ebrahimi 
7754*f5c631daSSadaf Ebrahimi   Emit(0x44128000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
7755*f5c631daSSadaf Ebrahimi }
7756*f5c631daSSadaf Ebrahimi 
shsubr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)7757*f5c631daSSadaf Ebrahimi void Assembler::shsubr(const ZRegister& zd,
7758*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
7759*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
7760*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
7761*f5c631daSSadaf Ebrahimi   // SHSUBR <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
7762*f5c631daSSadaf Ebrahimi   //  0100 0100 ..01 0110 100. .... .... ....
7763*f5c631daSSadaf Ebrahimi   //  size<23:22> | R<18> | S<17> | U<16> | Pg<12:10> | Zm<9:5> | Zdn<4:0>
7764*f5c631daSSadaf Ebrahimi 
7765*f5c631daSSadaf Ebrahimi   USE(zn);
7766*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7767*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
7768*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
7769*f5c631daSSadaf Ebrahimi 
7770*f5c631daSSadaf Ebrahimi   Emit(0x44168000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
7771*f5c631daSSadaf Ebrahimi }
7772*f5c631daSSadaf Ebrahimi 
sli(const ZRegister & zd,const ZRegister & zn,int shift)7773*f5c631daSSadaf Ebrahimi void Assembler::sli(const ZRegister& zd, const ZRegister& zn, int shift) {
7774*f5c631daSSadaf Ebrahimi   // SLI <Zd>.<T>, <Zn>.<T>, #<const>
7775*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 1111 01.. .... ....
7776*f5c631daSSadaf Ebrahimi   //  tszh<23:22> | tszl<20:19> | imm3<18:16> | op<10> | Zn<9:5> | Zd<4:0>
7777*f5c631daSSadaf Ebrahimi 
7778*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7779*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
7780*f5c631daSSadaf Ebrahimi   Instr encoded_imm =
7781*f5c631daSSadaf Ebrahimi       EncodeSVEShiftLeftImmediate(shift, zd.GetLaneSizeInBits());
7782*f5c631daSSadaf Ebrahimi 
7783*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediate(zd, zn, encoded_imm, 0x4500f400);
7784*f5c631daSSadaf Ebrahimi }
7785*f5c631daSSadaf Ebrahimi 
smaxp(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)7786*f5c631daSSadaf Ebrahimi void Assembler::smaxp(const ZRegister& zd,
7787*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
7788*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
7789*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
7790*f5c631daSSadaf Ebrahimi   // SMAXP <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
7791*f5c631daSSadaf Ebrahimi   //  0100 0100 ..01 0100 101. .... .... ....
7792*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:17> | U<16> | Pg<12:10> | Zm<9:5> | Zdn<4:0>
7793*f5c631daSSadaf Ebrahimi 
7794*f5c631daSSadaf Ebrahimi   USE(zn);
7795*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7796*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
7797*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
7798*f5c631daSSadaf Ebrahimi 
7799*f5c631daSSadaf Ebrahimi   Emit(0x4414a000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
7800*f5c631daSSadaf Ebrahimi }
7801*f5c631daSSadaf Ebrahimi 
sminp(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)7802*f5c631daSSadaf Ebrahimi void Assembler::sminp(const ZRegister& zd,
7803*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
7804*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
7805*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
7806*f5c631daSSadaf Ebrahimi   // SMINP <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
7807*f5c631daSSadaf Ebrahimi   //  0100 0100 ..01 0110 101. .... .... ....
7808*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:17> | U<16> | Pg<12:10> | Zm<9:5> | Zdn<4:0>
7809*f5c631daSSadaf Ebrahimi 
7810*f5c631daSSadaf Ebrahimi   USE(zn);
7811*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7812*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
7813*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
7814*f5c631daSSadaf Ebrahimi 
7815*f5c631daSSadaf Ebrahimi   Emit(0x4416a000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
7816*f5c631daSSadaf Ebrahimi }
7817*f5c631daSSadaf Ebrahimi 
7818*f5c631daSSadaf Ebrahimi #define VIXL_SVE_MULL_INDEX_LIST(V) \
7819*f5c631daSSadaf Ebrahimi   V(smullb, 0x44a0c000)             \
7820*f5c631daSSadaf Ebrahimi   V(smullt, 0x44a0c400)             \
7821*f5c631daSSadaf Ebrahimi   V(umullb, 0x44a0d000)             \
7822*f5c631daSSadaf Ebrahimi   V(umullt, 0x44a0d400)             \
7823*f5c631daSSadaf Ebrahimi   V(smlalb, 0x44a08000)             \
7824*f5c631daSSadaf Ebrahimi   V(smlalt, 0x44a08400)             \
7825*f5c631daSSadaf Ebrahimi   V(smlslb, 0x44a0a000)             \
7826*f5c631daSSadaf Ebrahimi   V(smlslt, 0x44a0a400)             \
7827*f5c631daSSadaf Ebrahimi   V(umlalb, 0x44a09000)             \
7828*f5c631daSSadaf Ebrahimi   V(umlalt, 0x44a09400)             \
7829*f5c631daSSadaf Ebrahimi   V(umlslb, 0x44a0b000)             \
7830*f5c631daSSadaf Ebrahimi   V(umlslt, 0x44a0b400)             \
7831*f5c631daSSadaf Ebrahimi   V(sqdmullb, 0x44a0e000)           \
7832*f5c631daSSadaf Ebrahimi   V(sqdmullt, 0x44a0e400)
7833*f5c631daSSadaf Ebrahimi 
7834*f5c631daSSadaf Ebrahimi #define VIXL_DEFINE_ASM_FUNC(MNE, OP)                                     \
7835*f5c631daSSadaf Ebrahimi   void Assembler::MNE(const ZRegister& zda,                               \
7836*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,                                \
7837*f5c631daSSadaf Ebrahimi                       const ZRegister& zm,                                \
7838*f5c631daSSadaf Ebrahimi                       int index) {                                        \
7839*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));                              \
7840*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(AreSameLaneSize(zn, zm));                                 \
7841*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zda.IsLaneSizeD() || zda.IsLaneSizeS());                  \
7842*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zda.GetLaneSizeInBytes() == zn.GetLaneSizeInBytes() * 2); \
7843*f5c631daSSadaf Ebrahimi     Instr zm_with_index = SVEMulLongIndexHelper(zm, index);               \
7844*f5c631daSSadaf Ebrahimi     Emit(OP | SVESize(zda) | Rd(zda) | Rn(zn) | zm_with_index);           \
7845*f5c631daSSadaf Ebrahimi   }
VIXL_SVE_MULL_INDEX_LIST(VIXL_DEFINE_ASM_FUNC)7846*f5c631daSSadaf Ebrahimi VIXL_SVE_MULL_INDEX_LIST(VIXL_DEFINE_ASM_FUNC)
7847*f5c631daSSadaf Ebrahimi #undef VIXL_DEFINE_ASM_FuNC
7848*f5c631daSSadaf Ebrahimi 
7849*f5c631daSSadaf Ebrahimi void Assembler::smlalb(const ZRegister& zda,
7850*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
7851*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
7852*f5c631daSSadaf Ebrahimi   // SMLALB <Zda>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
7853*f5c631daSSadaf Ebrahimi   //  0100 0100 ..0. .... 0100 00.. .... ....
7854*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<12> | U<11> | T<10> | Zn<9:5> | Zda<4:0>
7855*f5c631daSSadaf Ebrahimi 
7856*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7857*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zda.IsLaneSizeB());
7858*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
7859*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
7860*f5c631daSSadaf Ebrahimi 
7861*f5c631daSSadaf Ebrahimi   Emit(0x44004000 | SVESize(zda) | Rd(zda) | Rn(zn) | Rm(zm));
7862*f5c631daSSadaf Ebrahimi }
7863*f5c631daSSadaf Ebrahimi 
smlalt(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)7864*f5c631daSSadaf Ebrahimi void Assembler::smlalt(const ZRegister& zda,
7865*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
7866*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
7867*f5c631daSSadaf Ebrahimi   // SMLALT <Zda>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
7868*f5c631daSSadaf Ebrahimi   //  0100 0100 ..0. .... 0100 01.. .... ....
7869*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<12> | U<11> | T<10> | Zn<9:5> | Zda<4:0>
7870*f5c631daSSadaf Ebrahimi 
7871*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7872*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zda.IsLaneSizeB());
7873*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
7874*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
7875*f5c631daSSadaf Ebrahimi 
7876*f5c631daSSadaf Ebrahimi   Emit(0x44004400 | SVESize(zda) | Rd(zda) | Rn(zn) | Rm(zm));
7877*f5c631daSSadaf Ebrahimi }
7878*f5c631daSSadaf Ebrahimi 
smlslb(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)7879*f5c631daSSadaf Ebrahimi void Assembler::smlslb(const ZRegister& zda,
7880*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
7881*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
7882*f5c631daSSadaf Ebrahimi   // SMLSLB <Zda>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
7883*f5c631daSSadaf Ebrahimi   //  0100 0100 ..0. .... 0101 00.. .... ....
7884*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<12> | U<11> | T<10> | Zn<9:5> | Zda<4:0>
7885*f5c631daSSadaf Ebrahimi 
7886*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7887*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zda.IsLaneSizeB());
7888*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
7889*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
7890*f5c631daSSadaf Ebrahimi 
7891*f5c631daSSadaf Ebrahimi   Emit(0x44005000 | SVESize(zda) | Rd(zda) | Rn(zn) | Rm(zm));
7892*f5c631daSSadaf Ebrahimi }
7893*f5c631daSSadaf Ebrahimi 
smlslt(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)7894*f5c631daSSadaf Ebrahimi void Assembler::smlslt(const ZRegister& zda,
7895*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
7896*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
7897*f5c631daSSadaf Ebrahimi   // SMLSLT <Zda>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
7898*f5c631daSSadaf Ebrahimi   //  0100 0100 ..0. .... 0101 01.. .... ....
7899*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<12> | U<11> | T<10> | Zn<9:5> | Zda<4:0>
7900*f5c631daSSadaf Ebrahimi 
7901*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7902*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zda.IsLaneSizeB());
7903*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
7904*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
7905*f5c631daSSadaf Ebrahimi 
7906*f5c631daSSadaf Ebrahimi   Emit(0x44005400 | SVESize(zda) | Rd(zda) | Rn(zn) | Rm(zm));
7907*f5c631daSSadaf Ebrahimi }
7908*f5c631daSSadaf Ebrahimi 
smulh(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7909*f5c631daSSadaf Ebrahimi void Assembler::smulh(const ZRegister& zd,
7910*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
7911*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
7912*f5c631daSSadaf Ebrahimi   // SMULH <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
7913*f5c631daSSadaf Ebrahimi   //  0000 0100 ..1. .... 0110 10.. .... ....
7914*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<11:10> | Zn<9:5> | Zd<4:0>
7915*f5c631daSSadaf Ebrahimi 
7916*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7917*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
7918*f5c631daSSadaf Ebrahimi 
7919*f5c631daSSadaf Ebrahimi   Emit(0x04206800 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
7920*f5c631daSSadaf Ebrahimi }
7921*f5c631daSSadaf Ebrahimi 
smullb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7922*f5c631daSSadaf Ebrahimi void Assembler::smullb(const ZRegister& zd,
7923*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
7924*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
7925*f5c631daSSadaf Ebrahimi   // SMULLB <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
7926*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 0111 00.. .... ....
7927*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<12> | U<11> | T<10> | Zn<9:5> | Zd<4:0>
7928*f5c631daSSadaf Ebrahimi 
7929*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7930*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
7931*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zd.IsLaneSizeB() && !zd.IsLaneSizeQ());
7932*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == zn.GetLaneSizeInBytes() * 2);
7933*f5c631daSSadaf Ebrahimi 
7934*f5c631daSSadaf Ebrahimi   Emit(0x45007000 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
7935*f5c631daSSadaf Ebrahimi }
7936*f5c631daSSadaf Ebrahimi 
smullt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7937*f5c631daSSadaf Ebrahimi void Assembler::smullt(const ZRegister& zd,
7938*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
7939*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
7940*f5c631daSSadaf Ebrahimi   // SMULLT <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
7941*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 0111 01.. .... ....
7942*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<12> | U<11> | T<10> | Zn<9:5> | Zd<4:0>
7943*f5c631daSSadaf Ebrahimi 
7944*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7945*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
7946*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zd.IsLaneSizeB() && !zd.IsLaneSizeQ());
7947*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == zn.GetLaneSizeInBytes() * 2);
7948*f5c631daSSadaf Ebrahimi 
7949*f5c631daSSadaf Ebrahimi   Emit(0x45007400 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
7950*f5c631daSSadaf Ebrahimi }
7951*f5c631daSSadaf Ebrahimi 
sqabs(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)7952*f5c631daSSadaf Ebrahimi void Assembler::sqabs(const ZRegister& zd,
7953*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
7954*f5c631daSSadaf Ebrahimi                       const ZRegister& zn) {
7955*f5c631daSSadaf Ebrahimi   // SQABS <Zd>.<T>, <Pg>/M, <Zn>.<T>
7956*f5c631daSSadaf Ebrahimi   //  0100 0100 ..00 1000 101. .... .... ....
7957*f5c631daSSadaf Ebrahimi   //  size<23:22> | Q<19> | opc<17:16> | Pg<12:10> | Zn<9:5> | Zd<4:0>
7958*f5c631daSSadaf Ebrahimi 
7959*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7960*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
7961*f5c631daSSadaf Ebrahimi 
7962*f5c631daSSadaf Ebrahimi   Emit(0x4408a000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
7963*f5c631daSSadaf Ebrahimi }
7964*f5c631daSSadaf Ebrahimi 
sqadd(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)7965*f5c631daSSadaf Ebrahimi void Assembler::sqadd(const ZRegister& zd,
7966*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
7967*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
7968*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
7969*f5c631daSSadaf Ebrahimi   // SQADD <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
7970*f5c631daSSadaf Ebrahimi   //  0100 0100 ..01 1000 100. .... .... ....
7971*f5c631daSSadaf Ebrahimi   //  size<23:22> | op<18> | S<17> | U<16> | Pg<12:10> | Zm<9:5> | Zdn<4:0>
7972*f5c631daSSadaf Ebrahimi 
7973*f5c631daSSadaf Ebrahimi   USE(zn);
7974*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7975*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
7976*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
7977*f5c631daSSadaf Ebrahimi 
7978*f5c631daSSadaf Ebrahimi   Emit(0x44188000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
7979*f5c631daSSadaf Ebrahimi }
7980*f5c631daSSadaf Ebrahimi 
sqcadd(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm,int rot)7981*f5c631daSSadaf Ebrahimi void Assembler::sqcadd(const ZRegister& zd,
7982*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
7983*f5c631daSSadaf Ebrahimi                        const ZRegister& zm,
7984*f5c631daSSadaf Ebrahimi                        int rot) {
7985*f5c631daSSadaf Ebrahimi   // SQCADD <Zdn>.<T>, <Zdn>.<T>, <Zm>.<T>, <const>
7986*f5c631daSSadaf Ebrahimi   //  0100 0101 ..00 0001 1101 1... .... ....
7987*f5c631daSSadaf Ebrahimi   //  size<23:22> | op<16> | rot<10> | Zm<9:5> | Zdn<4:0>
7988*f5c631daSSadaf Ebrahimi 
7989*f5c631daSSadaf Ebrahimi   USE(zn);
7990*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
7991*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
7992*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
7993*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((rot == 90) || (rot == 270));
7994*f5c631daSSadaf Ebrahimi 
7995*f5c631daSSadaf Ebrahimi   Instr rotate_bit = (rot == 90) ? 0 : (1 << 10);
7996*f5c631daSSadaf Ebrahimi   Emit(0x4501d800 | rotate_bit | SVESize(zd) | Rd(zd) | Rn(zm));
7997*f5c631daSSadaf Ebrahimi }
7998*f5c631daSSadaf Ebrahimi 
7999*f5c631daSSadaf Ebrahimi // This prototype maps to 2 instruction encodings:
8000*f5c631daSSadaf Ebrahimi //  sqdmlalb_z_zzzi_d
8001*f5c631daSSadaf Ebrahimi //  sqdmlalb_z_zzzi_s
sqdmlalb(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm,int index)8002*f5c631daSSadaf Ebrahimi void Assembler::sqdmlalb(const ZRegister& zda,
8003*f5c631daSSadaf Ebrahimi                          const ZRegister& zn,
8004*f5c631daSSadaf Ebrahimi                          const ZRegister& zm,
8005*f5c631daSSadaf Ebrahimi                          int index) {
8006*f5c631daSSadaf Ebrahimi   // SQDMLALB <Zda>.D, <Zn>.S, <Zm>.S[<imm>]
8007*f5c631daSSadaf Ebrahimi   //  0100 0100 111. .... 0010 .0.. .... ....
8008*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<20:16> | S<12> | il<11> | T<10> | Zn<9:5> | Zda<4:0>
8009*f5c631daSSadaf Ebrahimi 
8010*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8011*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
8012*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.IsLaneSizeS() || zda.IsLaneSizeD());
8013*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(index >= 0);
8014*f5c631daSSadaf Ebrahimi 
8015*f5c631daSSadaf Ebrahimi   Instr zm_and_idx = 0;
8016*f5c631daSSadaf Ebrahimi   if (zm.IsLaneSizeH()) {
8017*f5c631daSSadaf Ebrahimi     // Zm<18:16> | i3h<20:19> | i3l<11>
8018*f5c631daSSadaf Ebrahimi     VIXL_ASSERT((zm.GetCode() <= 7) && (index <= 7));
8019*f5c631daSSadaf Ebrahimi     zm_and_idx = (ExtractUnsignedBitfield32(2, 1, index) << 19) |
8020*f5c631daSSadaf Ebrahimi                  (ExtractBit(index, 0) << 11) | Rx<18, 16>(zm);
8021*f5c631daSSadaf Ebrahimi   } else {
8022*f5c631daSSadaf Ebrahimi     // Zm<19:16> | i2h<20> | i2l<11>
8023*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zm.IsLaneSizeS());
8024*f5c631daSSadaf Ebrahimi     VIXL_ASSERT((zm.GetCode() <= 15) && (index <= 3));
8025*f5c631daSSadaf Ebrahimi     zm_and_idx = (ExtractBit(index, 1) << 20) | (ExtractBit(index, 0) << 11) |
8026*f5c631daSSadaf Ebrahimi                  Rx<19, 16>(zm);
8027*f5c631daSSadaf Ebrahimi   }
8028*f5c631daSSadaf Ebrahimi 
8029*f5c631daSSadaf Ebrahimi   Emit(0x44202000 | zm_and_idx | SVESize(zda) | Rd(zda) | Rn(zn));
8030*f5c631daSSadaf Ebrahimi }
8031*f5c631daSSadaf Ebrahimi 
sqdmlalb(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)8032*f5c631daSSadaf Ebrahimi void Assembler::sqdmlalb(const ZRegister& zda,
8033*f5c631daSSadaf Ebrahimi                          const ZRegister& zn,
8034*f5c631daSSadaf Ebrahimi                          const ZRegister& zm) {
8035*f5c631daSSadaf Ebrahimi   // SQDMLALB <Zda>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
8036*f5c631daSSadaf Ebrahimi   //  0100 0100 ..0. .... 0110 00.. .... ....
8037*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<11> | T<10> | Zn<9:5> | Zda<4:0>
8038*f5c631daSSadaf Ebrahimi 
8039*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8040*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
8041*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
8042*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() != kBRegSizeInBytes);
8043*f5c631daSSadaf Ebrahimi 
8044*f5c631daSSadaf Ebrahimi   Emit(0x44006000 | SVESize(zda) | Rd(zda) | Rn(zn) | Rm(zm));
8045*f5c631daSSadaf Ebrahimi }
8046*f5c631daSSadaf Ebrahimi 
sqdmlalbt(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)8047*f5c631daSSadaf Ebrahimi void Assembler::sqdmlalbt(const ZRegister& zda,
8048*f5c631daSSadaf Ebrahimi                           const ZRegister& zn,
8049*f5c631daSSadaf Ebrahimi                           const ZRegister& zm) {
8050*f5c631daSSadaf Ebrahimi   // SQDMLALBT <Zda>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
8051*f5c631daSSadaf Ebrahimi   //  0100 0100 ..0. .... 0000 10.. .... ....
8052*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<10> | Zn<9:5> | Zda<4:0>
8053*f5c631daSSadaf Ebrahimi 
8054*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8055*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
8056*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
8057*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() != kBRegSizeInBytes);
8058*f5c631daSSadaf Ebrahimi 
8059*f5c631daSSadaf Ebrahimi   Emit(0x44000800 | SVESize(zda) | Rd(zda) | Rn(zn) | Rm(zm));
8060*f5c631daSSadaf Ebrahimi }
8061*f5c631daSSadaf Ebrahimi 
8062*f5c631daSSadaf Ebrahimi // This prototype maps to 2 instruction encodings:
8063*f5c631daSSadaf Ebrahimi //  sqdmlalt_z_zzzi_d
8064*f5c631daSSadaf Ebrahimi //  sqdmlalt_z_zzzi_s
sqdmlalt(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm,int index)8065*f5c631daSSadaf Ebrahimi void Assembler::sqdmlalt(const ZRegister& zda,
8066*f5c631daSSadaf Ebrahimi                          const ZRegister& zn,
8067*f5c631daSSadaf Ebrahimi                          const ZRegister& zm,
8068*f5c631daSSadaf Ebrahimi                          int index) {
8069*f5c631daSSadaf Ebrahimi   // SQDMLALT <Zda>.D, <Zn>.S, <Zm>.S[<imm>]
8070*f5c631daSSadaf Ebrahimi   //  0100 0100 111. .... 0010 .1.. .... ....
8071*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<20:16> | S<12> | il<11> | T<10> | Zn<9:5> | Zda<4:0>
8072*f5c631daSSadaf Ebrahimi 
8073*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8074*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
8075*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.IsLaneSizeS() || zda.IsLaneSizeD());
8076*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(index >= 0);
8077*f5c631daSSadaf Ebrahimi 
8078*f5c631daSSadaf Ebrahimi   Instr zm_and_idx = 0;
8079*f5c631daSSadaf Ebrahimi   if (zm.IsLaneSizeH()) {
8080*f5c631daSSadaf Ebrahimi     // Zm<18:16> | i3h<20:19> | i3l<11>
8081*f5c631daSSadaf Ebrahimi     VIXL_ASSERT((zm.GetCode() <= 7) && (index <= 7));
8082*f5c631daSSadaf Ebrahimi     zm_and_idx = (ExtractUnsignedBitfield32(2, 1, index) << 19) |
8083*f5c631daSSadaf Ebrahimi                  (ExtractBit(index, 0) << 11) | Rx<18, 16>(zm);
8084*f5c631daSSadaf Ebrahimi   } else {
8085*f5c631daSSadaf Ebrahimi     // Zm<19:16> | i2h<20> | i2l<11>
8086*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zm.IsLaneSizeS());
8087*f5c631daSSadaf Ebrahimi     VIXL_ASSERT((zm.GetCode() <= 15) && (index <= 3));
8088*f5c631daSSadaf Ebrahimi     zm_and_idx = (ExtractBit(index, 1) << 20) | (ExtractBit(index, 0) << 11) |
8089*f5c631daSSadaf Ebrahimi                  Rx<19, 16>(zm);
8090*f5c631daSSadaf Ebrahimi   }
8091*f5c631daSSadaf Ebrahimi 
8092*f5c631daSSadaf Ebrahimi   Emit(0x44202400 | zm_and_idx | SVESize(zda) | Rd(zda) | Rn(zn));
8093*f5c631daSSadaf Ebrahimi }
8094*f5c631daSSadaf Ebrahimi 
sqdmlalt(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)8095*f5c631daSSadaf Ebrahimi void Assembler::sqdmlalt(const ZRegister& zda,
8096*f5c631daSSadaf Ebrahimi                          const ZRegister& zn,
8097*f5c631daSSadaf Ebrahimi                          const ZRegister& zm) {
8098*f5c631daSSadaf Ebrahimi   // SQDMLALT <Zda>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
8099*f5c631daSSadaf Ebrahimi   //  0100 0100 ..0. .... 0110 01.. .... ....
8100*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<11> | T<10> | Zn<9:5> | Zda<4:0>
8101*f5c631daSSadaf Ebrahimi 
8102*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8103*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
8104*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
8105*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() != kBRegSizeInBytes);
8106*f5c631daSSadaf Ebrahimi 
8107*f5c631daSSadaf Ebrahimi   Emit(0x44006400 | SVESize(zda) | Rd(zda) | Rn(zn) | Rm(zm));
8108*f5c631daSSadaf Ebrahimi }
8109*f5c631daSSadaf Ebrahimi 
8110*f5c631daSSadaf Ebrahimi // This prototype maps to 2 instruction encodings:
8111*f5c631daSSadaf Ebrahimi //  sqdmlslb_z_zzzi_d
8112*f5c631daSSadaf Ebrahimi //  sqdmlslb_z_zzzi_s
sqdmlslb(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm,int index)8113*f5c631daSSadaf Ebrahimi void Assembler::sqdmlslb(const ZRegister& zda,
8114*f5c631daSSadaf Ebrahimi                          const ZRegister& zn,
8115*f5c631daSSadaf Ebrahimi                          const ZRegister& zm,
8116*f5c631daSSadaf Ebrahimi                          int index) {
8117*f5c631daSSadaf Ebrahimi   // SQDMLSLB <Zda>.D, <Zn>.S, <Zm>.S[<imm>]
8118*f5c631daSSadaf Ebrahimi   //  0100 0100 111. .... 0011 .0.. .... ....
8119*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<20:16> | S<12> | il<11> | T<10> | Zn<9:5> | Zda<4:0>
8120*f5c631daSSadaf Ebrahimi 
8121*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8122*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
8123*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.IsLaneSizeS() || zda.IsLaneSizeD());
8124*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(index >= 0);
8125*f5c631daSSadaf Ebrahimi 
8126*f5c631daSSadaf Ebrahimi   Instr zm_and_idx = 0;
8127*f5c631daSSadaf Ebrahimi   if (zm.IsLaneSizeH()) {
8128*f5c631daSSadaf Ebrahimi     // Zm<18:16> | i3h<20:19> | i3l<11>
8129*f5c631daSSadaf Ebrahimi     VIXL_ASSERT((zm.GetCode() <= 7) && (index <= 7));
8130*f5c631daSSadaf Ebrahimi     zm_and_idx = (ExtractUnsignedBitfield32(2, 1, index) << 19) |
8131*f5c631daSSadaf Ebrahimi                  (ExtractBit(index, 0) << 11) | Rx<18, 16>(zm);
8132*f5c631daSSadaf Ebrahimi   } else {
8133*f5c631daSSadaf Ebrahimi     // Zm<19:16> | i2h<20> | i2l<11>
8134*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zm.IsLaneSizeS());
8135*f5c631daSSadaf Ebrahimi     VIXL_ASSERT((zm.GetCode() <= 15) && (index <= 3));
8136*f5c631daSSadaf Ebrahimi     zm_and_idx = (ExtractBit(index, 1) << 20) | (ExtractBit(index, 0) << 11) |
8137*f5c631daSSadaf Ebrahimi                  Rx<19, 16>(zm);
8138*f5c631daSSadaf Ebrahimi   }
8139*f5c631daSSadaf Ebrahimi 
8140*f5c631daSSadaf Ebrahimi   Emit(0x44203000 | zm_and_idx | SVESize(zda) | Rd(zda) | Rn(zn));
8141*f5c631daSSadaf Ebrahimi }
8142*f5c631daSSadaf Ebrahimi 
sqdmlslb(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)8143*f5c631daSSadaf Ebrahimi void Assembler::sqdmlslb(const ZRegister& zda,
8144*f5c631daSSadaf Ebrahimi                          const ZRegister& zn,
8145*f5c631daSSadaf Ebrahimi                          const ZRegister& zm) {
8146*f5c631daSSadaf Ebrahimi   // SQDMLSLB <Zda>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
8147*f5c631daSSadaf Ebrahimi   //  0100 0100 ..0. .... 0110 10.. .... ....
8148*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<11> | T<10> | Zn<9:5> | Zda<4:0>
8149*f5c631daSSadaf Ebrahimi 
8150*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8151*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
8152*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
8153*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() != kBRegSizeInBytes);
8154*f5c631daSSadaf Ebrahimi 
8155*f5c631daSSadaf Ebrahimi   Emit(0x44006800 | SVESize(zda) | Rd(zda) | Rn(zn) | Rm(zm));
8156*f5c631daSSadaf Ebrahimi }
8157*f5c631daSSadaf Ebrahimi 
sqdmlslbt(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)8158*f5c631daSSadaf Ebrahimi void Assembler::sqdmlslbt(const ZRegister& zda,
8159*f5c631daSSadaf Ebrahimi                           const ZRegister& zn,
8160*f5c631daSSadaf Ebrahimi                           const ZRegister& zm) {
8161*f5c631daSSadaf Ebrahimi   // SQDMLSLBT <Zda>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
8162*f5c631daSSadaf Ebrahimi   //  0100 0100 ..0. .... 0000 11.. .... ....
8163*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<10> | Zn<9:5> | Zda<4:0>
8164*f5c631daSSadaf Ebrahimi 
8165*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8166*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
8167*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
8168*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() != kBRegSizeInBytes);
8169*f5c631daSSadaf Ebrahimi 
8170*f5c631daSSadaf Ebrahimi   Emit(0x44000c00 | SVESize(zda) | Rd(zda) | Rn(zn) | Rm(zm));
8171*f5c631daSSadaf Ebrahimi }
8172*f5c631daSSadaf Ebrahimi 
8173*f5c631daSSadaf Ebrahimi // This prototype maps to 2 instruction encodings:
8174*f5c631daSSadaf Ebrahimi //  sqdmlslt_z_zzzi_d
8175*f5c631daSSadaf Ebrahimi //  sqdmlslt_z_zzzi_s
sqdmlslt(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm,int index)8176*f5c631daSSadaf Ebrahimi void Assembler::sqdmlslt(const ZRegister& zda,
8177*f5c631daSSadaf Ebrahimi                          const ZRegister& zn,
8178*f5c631daSSadaf Ebrahimi                          const ZRegister& zm,
8179*f5c631daSSadaf Ebrahimi                          int index) {
8180*f5c631daSSadaf Ebrahimi   // SQDMLSLT <Zda>.D, <Zn>.S, <Zm>.S[<imm>]
8181*f5c631daSSadaf Ebrahimi   //  0100 0100 111. .... 0011 .1.. .... ....
8182*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<20:16> | S<12> | il<11> | T<10> | Zn<9:5> | Zda<4:0>
8183*f5c631daSSadaf Ebrahimi 
8184*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8185*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
8186*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.IsLaneSizeS() || zda.IsLaneSizeD());
8187*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(index >= 0);
8188*f5c631daSSadaf Ebrahimi 
8189*f5c631daSSadaf Ebrahimi   Instr zm_and_idx = 0;
8190*f5c631daSSadaf Ebrahimi   if (zm.IsLaneSizeH()) {
8191*f5c631daSSadaf Ebrahimi     // Zm<18:16> | i3h<20:19> | i3l<11>
8192*f5c631daSSadaf Ebrahimi     VIXL_ASSERT((zm.GetCode() <= 7) && (index <= 7));
8193*f5c631daSSadaf Ebrahimi     zm_and_idx = (ExtractUnsignedBitfield32(2, 1, index) << 19) |
8194*f5c631daSSadaf Ebrahimi                  (ExtractBit(index, 0) << 11) | Rx<18, 16>(zm);
8195*f5c631daSSadaf Ebrahimi   } else {
8196*f5c631daSSadaf Ebrahimi     // Zm<19:16> | i2h<20> | i2l<11>
8197*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(zm.IsLaneSizeS());
8198*f5c631daSSadaf Ebrahimi     VIXL_ASSERT((zm.GetCode() <= 15) && (index <= 3));
8199*f5c631daSSadaf Ebrahimi     zm_and_idx = (ExtractBit(index, 1) << 20) | (ExtractBit(index, 0) << 11) |
8200*f5c631daSSadaf Ebrahimi                  Rx<19, 16>(zm);
8201*f5c631daSSadaf Ebrahimi   }
8202*f5c631daSSadaf Ebrahimi 
8203*f5c631daSSadaf Ebrahimi   Emit(0x44203400 | zm_and_idx | SVESize(zda) | Rd(zda) | Rn(zn));
8204*f5c631daSSadaf Ebrahimi }
8205*f5c631daSSadaf Ebrahimi 
sqdmlslt(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)8206*f5c631daSSadaf Ebrahimi void Assembler::sqdmlslt(const ZRegister& zda,
8207*f5c631daSSadaf Ebrahimi                          const ZRegister& zn,
8208*f5c631daSSadaf Ebrahimi                          const ZRegister& zm) {
8209*f5c631daSSadaf Ebrahimi   // SQDMLSLT <Zda>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
8210*f5c631daSSadaf Ebrahimi   //  0100 0100 ..0. .... 0110 11.. .... ....
8211*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<11> | T<10> | Zn<9:5> | Zda<4:0>
8212*f5c631daSSadaf Ebrahimi 
8213*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8214*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
8215*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
8216*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() != kBRegSizeInBytes);
8217*f5c631daSSadaf Ebrahimi 
8218*f5c631daSSadaf Ebrahimi   Emit(0x44006c00 | SVESize(zda) | Rd(zda) | Rn(zn) | Rm(zm));
8219*f5c631daSSadaf Ebrahimi }
8220*f5c631daSSadaf Ebrahimi 
sqdmulh(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm,int index)8221*f5c631daSSadaf Ebrahimi void Assembler::sqdmulh(const ZRegister& zd,
8222*f5c631daSSadaf Ebrahimi                         const ZRegister& zn,
8223*f5c631daSSadaf Ebrahimi                         const ZRegister& zm,
8224*f5c631daSSadaf Ebrahimi                         int index) {
8225*f5c631daSSadaf Ebrahimi   // SQDMULH <Zd>.D, <Zn>.D, <Zm>.D[<imm>]
8226*f5c631daSSadaf Ebrahimi   //  0100 0100 111. .... 1111 00.. .... ....
8227*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<20:16> | R<10> | Zn<9:5> | Zd<4:0>
8228*f5c631daSSadaf Ebrahimi 
8229*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8230*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
8231*f5c631daSSadaf Ebrahimi 
8232*f5c631daSSadaf Ebrahimi   Instr synthesised_op = SVEMulIndexHelper(zd.GetLaneSizeInBytesLog2(),
8233*f5c631daSSadaf Ebrahimi                                            zm,
8234*f5c631daSSadaf Ebrahimi                                            index,
8235*f5c631daSSadaf Ebrahimi                                            0x4420f000,
8236*f5c631daSSadaf Ebrahimi                                            0x44a0f000,
8237*f5c631daSSadaf Ebrahimi                                            0x44e0f000);
8238*f5c631daSSadaf Ebrahimi 
8239*f5c631daSSadaf Ebrahimi   Emit(synthesised_op | Rd(zd) | Rn(zn));
8240*f5c631daSSadaf Ebrahimi }
8241*f5c631daSSadaf Ebrahimi 
sqdmulh(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)8242*f5c631daSSadaf Ebrahimi void Assembler::sqdmulh(const ZRegister& zd,
8243*f5c631daSSadaf Ebrahimi                         const ZRegister& zn,
8244*f5c631daSSadaf Ebrahimi                         const ZRegister& zm) {
8245*f5c631daSSadaf Ebrahimi   // SQDMULH <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
8246*f5c631daSSadaf Ebrahimi   //  0000 0100 ..1. .... 0111 00.. .... ....
8247*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | R<10> | Zn<9:5> | Zd<4:0>
8248*f5c631daSSadaf Ebrahimi 
8249*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8250*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
8251*f5c631daSSadaf Ebrahimi 
8252*f5c631daSSadaf Ebrahimi   Emit(0x04207000 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
8253*f5c631daSSadaf Ebrahimi }
8254*f5c631daSSadaf Ebrahimi 
sqdmullb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)8255*f5c631daSSadaf Ebrahimi void Assembler::sqdmullb(const ZRegister& zd,
8256*f5c631daSSadaf Ebrahimi                          const ZRegister& zn,
8257*f5c631daSSadaf Ebrahimi                          const ZRegister& zm) {
8258*f5c631daSSadaf Ebrahimi   // SQDMULLB <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
8259*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 0110 00.. .... ....
8260*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<12> | U<11> | T<10> | Zn<9:5> | Zd<4:0>
8261*f5c631daSSadaf Ebrahimi 
8262*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8263*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
8264*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zd.IsLaneSizeB() && !zd.IsLaneSizeQ());
8265*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == zn.GetLaneSizeInBytes() * 2);
8266*f5c631daSSadaf Ebrahimi 
8267*f5c631daSSadaf Ebrahimi   Emit(0x45006000 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
8268*f5c631daSSadaf Ebrahimi }
8269*f5c631daSSadaf Ebrahimi 
sqdmullt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)8270*f5c631daSSadaf Ebrahimi void Assembler::sqdmullt(const ZRegister& zd,
8271*f5c631daSSadaf Ebrahimi                          const ZRegister& zn,
8272*f5c631daSSadaf Ebrahimi                          const ZRegister& zm) {
8273*f5c631daSSadaf Ebrahimi   // SQDMULLT <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
8274*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 0110 01.. .... ....
8275*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<12> | U<11> | T<10> | Zn<9:5> | Zd<4:0>
8276*f5c631daSSadaf Ebrahimi 
8277*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8278*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
8279*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zd.IsLaneSizeB() && !zd.IsLaneSizeQ());
8280*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == zn.GetLaneSizeInBytes() * 2);
8281*f5c631daSSadaf Ebrahimi 
8282*f5c631daSSadaf Ebrahimi   Emit(0x45006400 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
8283*f5c631daSSadaf Ebrahimi }
8284*f5c631daSSadaf Ebrahimi 
sqneg(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)8285*f5c631daSSadaf Ebrahimi void Assembler::sqneg(const ZRegister& zd,
8286*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
8287*f5c631daSSadaf Ebrahimi                       const ZRegister& zn) {
8288*f5c631daSSadaf Ebrahimi   // SQNEG <Zd>.<T>, <Pg>/M, <Zn>.<T>
8289*f5c631daSSadaf Ebrahimi   //  0100 0100 ..00 1001 101. .... .... ....
8290*f5c631daSSadaf Ebrahimi   //  size<23:22> | Q<19> | opc<17:16> | Pg<12:10> | Zn<9:5> | Zd<4:0>
8291*f5c631daSSadaf Ebrahimi 
8292*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8293*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
8294*f5c631daSSadaf Ebrahimi 
8295*f5c631daSSadaf Ebrahimi   Emit(0x4409a000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
8296*f5c631daSSadaf Ebrahimi }
8297*f5c631daSSadaf Ebrahimi 
sqrdcmlah(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm,int index,int rot)8298*f5c631daSSadaf Ebrahimi void Assembler::sqrdcmlah(const ZRegister& zda,
8299*f5c631daSSadaf Ebrahimi                           const ZRegister& zn,
8300*f5c631daSSadaf Ebrahimi                           const ZRegister& zm,
8301*f5c631daSSadaf Ebrahimi                           int index,
8302*f5c631daSSadaf Ebrahimi                           int rot) {
8303*f5c631daSSadaf Ebrahimi   // SQRDCMLAH <Zda>.H, <Zn>.H, <Zm>.H[<imm>], <const>
8304*f5c631daSSadaf Ebrahimi   //  0100 0100 101. .... 0111 .... .... ....
8305*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<20:16> | rot<11:10> | Zn<9:5> | Zda<4:0>
8306*f5c631daSSadaf Ebrahimi 
8307*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8308*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn, zm));
8309*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((rot == 0) || (rot == 90) || (rot == 180) || (rot == 270));
8310*f5c631daSSadaf Ebrahimi 
8311*f5c631daSSadaf Ebrahimi   Instr rotate_bit = (rot / 90) << 10;
8312*f5c631daSSadaf Ebrahimi   Emit(0x44a07000 | SVEMulComplexIndexHelper(zm, index) | rotate_bit | Rd(zda) |
8313*f5c631daSSadaf Ebrahimi        Rn(zn));
8314*f5c631daSSadaf Ebrahimi }
8315*f5c631daSSadaf Ebrahimi 
sqrdcmlah(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm,int rot)8316*f5c631daSSadaf Ebrahimi void Assembler::sqrdcmlah(const ZRegister& zda,
8317*f5c631daSSadaf Ebrahimi                           const ZRegister& zn,
8318*f5c631daSSadaf Ebrahimi                           const ZRegister& zm,
8319*f5c631daSSadaf Ebrahimi                           int rot) {
8320*f5c631daSSadaf Ebrahimi   // SQRDCMLAH <Zda>.<T>, <Zn>.<T>, <Zm>.<T>, <const>
8321*f5c631daSSadaf Ebrahimi   //  0100 0100 ..0. .... 0011 .... .... ....
8322*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<12> | rot<11:10> | Zn<9:5> | Zda<4:0>
8323*f5c631daSSadaf Ebrahimi 
8324*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8325*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn, zm));
8326*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((rot == 0) || (rot == 90) || (rot == 180) || (rot == 270));
8327*f5c631daSSadaf Ebrahimi 
8328*f5c631daSSadaf Ebrahimi   Instr rotate_bit = (rot / 90) << 10;
8329*f5c631daSSadaf Ebrahimi   Emit(0x44003000 | rotate_bit | SVESize(zda) | Rd(zda) | Rn(zn) | Rm(zm));
8330*f5c631daSSadaf Ebrahimi }
8331*f5c631daSSadaf Ebrahimi 
8332*f5c631daSSadaf Ebrahimi // This prototype maps to 3 instruction encodings:
8333*f5c631daSSadaf Ebrahimi //  sqrdmlah_z_zzzi_d
8334*f5c631daSSadaf Ebrahimi //  sqrdmlah_z_zzzi_h
8335*f5c631daSSadaf Ebrahimi //  sqrdmlah_z_zzzi_s
sqrdmlah(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm,int index)8336*f5c631daSSadaf Ebrahimi void Assembler::sqrdmlah(const ZRegister& zda,
8337*f5c631daSSadaf Ebrahimi                          const ZRegister& zn,
8338*f5c631daSSadaf Ebrahimi                          const ZRegister& zm,
8339*f5c631daSSadaf Ebrahimi                          int index) {
8340*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8341*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn, zm));
8342*f5c631daSSadaf Ebrahimi 
8343*f5c631daSSadaf Ebrahimi   Instr op_h = 0x44201000;
8344*f5c631daSSadaf Ebrahimi   Instr op_s = op_h | (1 << 23);
8345*f5c631daSSadaf Ebrahimi   Instr op_d = op_h | (3 << 22);
8346*f5c631daSSadaf Ebrahimi   // The encoding of opcode, index, Zm, and size are synthesized in this
8347*f5c631daSSadaf Ebrahimi   // variable.
8348*f5c631daSSadaf Ebrahimi   Instr synthesized_op = SVEMulIndexHelper(zda.GetLaneSizeInBytesLog2(),
8349*f5c631daSSadaf Ebrahimi                                            zm,
8350*f5c631daSSadaf Ebrahimi                                            index,
8351*f5c631daSSadaf Ebrahimi                                            op_h,
8352*f5c631daSSadaf Ebrahimi                                            op_s,
8353*f5c631daSSadaf Ebrahimi                                            op_d);
8354*f5c631daSSadaf Ebrahimi 
8355*f5c631daSSadaf Ebrahimi   Emit(synthesized_op | Rd(zda) | Rn(zn));
8356*f5c631daSSadaf Ebrahimi }
8357*f5c631daSSadaf Ebrahimi 
sqrdmlah(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)8358*f5c631daSSadaf Ebrahimi void Assembler::sqrdmlah(const ZRegister& zda,
8359*f5c631daSSadaf Ebrahimi                          const ZRegister& zn,
8360*f5c631daSSadaf Ebrahimi                          const ZRegister& zm) {
8361*f5c631daSSadaf Ebrahimi   // SQRDMLAH <Zda>.<T>, <Zn>.<T>, <Zm>.<T>
8362*f5c631daSSadaf Ebrahimi   //  0100 0100 ..0. .... 0111 00.. .... ....
8363*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<10> | Zn<9:5> | Zda<4:0>
8364*f5c631daSSadaf Ebrahimi 
8365*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8366*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn, zm));
8367*f5c631daSSadaf Ebrahimi 
8368*f5c631daSSadaf Ebrahimi   Emit(0x44007000 | SVESize(zda) | Rd(zda) | Rn(zn) | Rm(zm));
8369*f5c631daSSadaf Ebrahimi }
8370*f5c631daSSadaf Ebrahimi 
8371*f5c631daSSadaf Ebrahimi // This prototype maps to 3 instruction encodings:
8372*f5c631daSSadaf Ebrahimi //  sqrdmlsh_z_zzzi_d
8373*f5c631daSSadaf Ebrahimi //  sqrdmlsh_z_zzzi_h
8374*f5c631daSSadaf Ebrahimi //  sqrdmlsh_z_zzzi_s
sqrdmlsh(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm,int index)8375*f5c631daSSadaf Ebrahimi void Assembler::sqrdmlsh(const ZRegister& zda,
8376*f5c631daSSadaf Ebrahimi                          const ZRegister& zn,
8377*f5c631daSSadaf Ebrahimi                          const ZRegister& zm,
8378*f5c631daSSadaf Ebrahimi                          int index) {
8379*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8380*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn, zm));
8381*f5c631daSSadaf Ebrahimi 
8382*f5c631daSSadaf Ebrahimi   Instr op_h = 0x44201400;
8383*f5c631daSSadaf Ebrahimi   Instr op_s = op_h | (1 << 23);
8384*f5c631daSSadaf Ebrahimi   Instr op_d = op_h | (3 << 22);
8385*f5c631daSSadaf Ebrahimi   // The encoding of opcode, index, Zm, and size are synthesized in this
8386*f5c631daSSadaf Ebrahimi   // variable.
8387*f5c631daSSadaf Ebrahimi   Instr synthesized_op = SVEMulIndexHelper(zda.GetLaneSizeInBytesLog2(),
8388*f5c631daSSadaf Ebrahimi                                            zm,
8389*f5c631daSSadaf Ebrahimi                                            index,
8390*f5c631daSSadaf Ebrahimi                                            op_h,
8391*f5c631daSSadaf Ebrahimi                                            op_s,
8392*f5c631daSSadaf Ebrahimi                                            op_d);
8393*f5c631daSSadaf Ebrahimi 
8394*f5c631daSSadaf Ebrahimi   Emit(synthesized_op | Rd(zda) | Rn(zn));
8395*f5c631daSSadaf Ebrahimi }
8396*f5c631daSSadaf Ebrahimi 
sqrdmlsh(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)8397*f5c631daSSadaf Ebrahimi void Assembler::sqrdmlsh(const ZRegister& zda,
8398*f5c631daSSadaf Ebrahimi                          const ZRegister& zn,
8399*f5c631daSSadaf Ebrahimi                          const ZRegister& zm) {
8400*f5c631daSSadaf Ebrahimi   // SQRDMLSH <Zda>.<T>, <Zn>.<T>, <Zm>.<T>
8401*f5c631daSSadaf Ebrahimi   //  0100 0100 ..0. .... 0111 01.. .... ....
8402*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<10> | Zn<9:5> | Zda<4:0>
8403*f5c631daSSadaf Ebrahimi 
8404*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8405*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn, zm));
8406*f5c631daSSadaf Ebrahimi 
8407*f5c631daSSadaf Ebrahimi   Emit(0x44007400 | SVESize(zda) | Rd(zda) | Rn(zn) | Rm(zm));
8408*f5c631daSSadaf Ebrahimi }
8409*f5c631daSSadaf Ebrahimi 
sqrdmulh(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm,int index)8410*f5c631daSSadaf Ebrahimi void Assembler::sqrdmulh(const ZRegister& zd,
8411*f5c631daSSadaf Ebrahimi                          const ZRegister& zn,
8412*f5c631daSSadaf Ebrahimi                          const ZRegister& zm,
8413*f5c631daSSadaf Ebrahimi                          int index) {
8414*f5c631daSSadaf Ebrahimi   // SQRDMULH <Zd>.D, <Zn>.D, <Zm>.D[<imm>]
8415*f5c631daSSadaf Ebrahimi   //  0100 0100 111. .... 1111 01.. .... ....
8416*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<20:16> | R<10> | Zn<9:5> | Zd<4:0>
8417*f5c631daSSadaf Ebrahimi 
8418*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8419*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
8420*f5c631daSSadaf Ebrahimi 
8421*f5c631daSSadaf Ebrahimi   Instr synthesised_op = SVEMulIndexHelper(zd.GetLaneSizeInBytesLog2(),
8422*f5c631daSSadaf Ebrahimi                                            zm,
8423*f5c631daSSadaf Ebrahimi                                            index,
8424*f5c631daSSadaf Ebrahimi                                            0x4420f400,
8425*f5c631daSSadaf Ebrahimi                                            0x44a0f400,
8426*f5c631daSSadaf Ebrahimi                                            0x44e0f400);
8427*f5c631daSSadaf Ebrahimi 
8428*f5c631daSSadaf Ebrahimi   Emit(synthesised_op | Rd(zd) | Rn(zn));
8429*f5c631daSSadaf Ebrahimi }
8430*f5c631daSSadaf Ebrahimi 
sqrdmulh(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)8431*f5c631daSSadaf Ebrahimi void Assembler::sqrdmulh(const ZRegister& zd,
8432*f5c631daSSadaf Ebrahimi                          const ZRegister& zn,
8433*f5c631daSSadaf Ebrahimi                          const ZRegister& zm) {
8434*f5c631daSSadaf Ebrahimi   // SQRDMULH <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
8435*f5c631daSSadaf Ebrahimi   //  0000 0100 ..1. .... 0111 01.. .... ....
8436*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | R<10> | Zn<9:5> | Zd<4:0>
8437*f5c631daSSadaf Ebrahimi 
8438*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8439*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
8440*f5c631daSSadaf Ebrahimi 
8441*f5c631daSSadaf Ebrahimi   Emit(0x04207400 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
8442*f5c631daSSadaf Ebrahimi }
8443*f5c631daSSadaf Ebrahimi 
sqrshl(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)8444*f5c631daSSadaf Ebrahimi void Assembler::sqrshl(const ZRegister& zd,
8445*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
8446*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
8447*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
8448*f5c631daSSadaf Ebrahimi   // SQRSHL <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
8449*f5c631daSSadaf Ebrahimi   //  0100 0100 ..00 1010 100. .... .... ....
8450*f5c631daSSadaf Ebrahimi   //  size<23:22> | Q<19> | R<18> | N<17> | U<16> | Pg<12:10> | Zm<9:5> |
8451*f5c631daSSadaf Ebrahimi   //  Zdn<4:0>
8452*f5c631daSSadaf Ebrahimi 
8453*f5c631daSSadaf Ebrahimi   USE(zn);
8454*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8455*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
8456*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
8457*f5c631daSSadaf Ebrahimi 
8458*f5c631daSSadaf Ebrahimi   Emit(0x440a8000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
8459*f5c631daSSadaf Ebrahimi }
8460*f5c631daSSadaf Ebrahimi 
sqrshlr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)8461*f5c631daSSadaf Ebrahimi void Assembler::sqrshlr(const ZRegister& zd,
8462*f5c631daSSadaf Ebrahimi                         const PRegisterM& pg,
8463*f5c631daSSadaf Ebrahimi                         const ZRegister& zn,
8464*f5c631daSSadaf Ebrahimi                         const ZRegister& zm) {
8465*f5c631daSSadaf Ebrahimi   // SQRSHLR <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
8466*f5c631daSSadaf Ebrahimi   //  0100 0100 ..00 1110 100. .... .... ....
8467*f5c631daSSadaf Ebrahimi   //  size<23:22> | Q<19> | R<18> | N<17> | U<16> | Pg<12:10> | Zm<9:5> |
8468*f5c631daSSadaf Ebrahimi   //  Zdn<4:0>
8469*f5c631daSSadaf Ebrahimi 
8470*f5c631daSSadaf Ebrahimi   USE(zn);
8471*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8472*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
8473*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
8474*f5c631daSSadaf Ebrahimi 
8475*f5c631daSSadaf Ebrahimi   Emit(0x440e8000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
8476*f5c631daSSadaf Ebrahimi }
8477*f5c631daSSadaf Ebrahimi 
sqshl(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,int shift)8478*f5c631daSSadaf Ebrahimi void Assembler::sqshl(const ZRegister& zd,
8479*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
8480*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
8481*f5c631daSSadaf Ebrahimi                       int shift) {
8482*f5c631daSSadaf Ebrahimi   // SQSHL <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, #<const>
8483*f5c631daSSadaf Ebrahimi   //  0000 0100 ..00 0110 100. .... .... ....
8484*f5c631daSSadaf Ebrahimi   //  tszh<23:22> | opc<19:18> | L<17> | U<16> | Pg<12:10> | tszl<9:8> |
8485*f5c631daSSadaf Ebrahimi   //  imm3<7:5> | Zdn<4:0>
8486*f5c631daSSadaf Ebrahimi 
8487*f5c631daSSadaf Ebrahimi   USE(zn);
8488*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8489*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
8490*f5c631daSSadaf Ebrahimi   Instr encoded_imm =
8491*f5c631daSSadaf Ebrahimi       EncodeSVEShiftLeftImmediate(shift, zd.GetLaneSizeInBits());
8492*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediatePred(zd, pg, encoded_imm, 0x04068000);
8493*f5c631daSSadaf Ebrahimi }
8494*f5c631daSSadaf Ebrahimi 
sqshl(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)8495*f5c631daSSadaf Ebrahimi void Assembler::sqshl(const ZRegister& zd,
8496*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
8497*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
8498*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
8499*f5c631daSSadaf Ebrahimi   // SQSHL <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
8500*f5c631daSSadaf Ebrahimi   //  0100 0100 ..00 1000 100. .... .... ....
8501*f5c631daSSadaf Ebrahimi   //  size<23:22> | Q<19> | R<18> | N<17> | U<16> | Pg<12:10> | Zm<9:5> |
8502*f5c631daSSadaf Ebrahimi   //  Zdn<4:0>
8503*f5c631daSSadaf Ebrahimi 
8504*f5c631daSSadaf Ebrahimi   USE(zn);
8505*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8506*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
8507*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
8508*f5c631daSSadaf Ebrahimi 
8509*f5c631daSSadaf Ebrahimi   Emit(0x44088000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
8510*f5c631daSSadaf Ebrahimi }
8511*f5c631daSSadaf Ebrahimi 
sqshlr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)8512*f5c631daSSadaf Ebrahimi void Assembler::sqshlr(const ZRegister& zd,
8513*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
8514*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
8515*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
8516*f5c631daSSadaf Ebrahimi   // SQSHLR <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
8517*f5c631daSSadaf Ebrahimi   //  0100 0100 ..00 1100 100. .... .... ....
8518*f5c631daSSadaf Ebrahimi   //  size<23:22> | Q<19> | R<18> | N<17> | U<16> | Pg<12:10> | Zm<9:5> |
8519*f5c631daSSadaf Ebrahimi   //  Zdn<4:0>
8520*f5c631daSSadaf Ebrahimi 
8521*f5c631daSSadaf Ebrahimi   USE(zn);
8522*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8523*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
8524*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
8525*f5c631daSSadaf Ebrahimi 
8526*f5c631daSSadaf Ebrahimi   Emit(0x440c8000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
8527*f5c631daSSadaf Ebrahimi }
8528*f5c631daSSadaf Ebrahimi 
sqshlu(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,int shift)8529*f5c631daSSadaf Ebrahimi void Assembler::sqshlu(const ZRegister& zd,
8530*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
8531*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
8532*f5c631daSSadaf Ebrahimi                        int shift) {
8533*f5c631daSSadaf Ebrahimi   // SQSHLU <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, #<const>
8534*f5c631daSSadaf Ebrahimi   //  0000 0100 ..00 1111 100. .... .... ....
8535*f5c631daSSadaf Ebrahimi   //  tszh<23:22> | opc<19:18> | L<17> | U<16> | Pg<12:10> | tszl<9:8> |
8536*f5c631daSSadaf Ebrahimi   //  imm3<7:5> | Zdn<4:0>
8537*f5c631daSSadaf Ebrahimi 
8538*f5c631daSSadaf Ebrahimi   USE(zn);
8539*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8540*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
8541*f5c631daSSadaf Ebrahimi 
8542*f5c631daSSadaf Ebrahimi   Instr encoded_imm =
8543*f5c631daSSadaf Ebrahimi       EncodeSVEShiftLeftImmediate(shift, zd.GetLaneSizeInBits());
8544*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediatePred(zd, pg, encoded_imm, 0x040f8000);
8545*f5c631daSSadaf Ebrahimi }
8546*f5c631daSSadaf Ebrahimi 
sqsub(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)8547*f5c631daSSadaf Ebrahimi void Assembler::sqsub(const ZRegister& zd,
8548*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
8549*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
8550*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
8551*f5c631daSSadaf Ebrahimi   // SQSUB <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
8552*f5c631daSSadaf Ebrahimi   //  0100 0100 ..01 1010 100. .... .... ....
8553*f5c631daSSadaf Ebrahimi   //  size<23:22> | op<18> | S<17> | U<16> | Pg<12:10> | Zm<9:5> | Zdn<4:0>
8554*f5c631daSSadaf Ebrahimi 
8555*f5c631daSSadaf Ebrahimi   USE(zn);
8556*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8557*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
8558*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
8559*f5c631daSSadaf Ebrahimi 
8560*f5c631daSSadaf Ebrahimi   Emit(0x441a8000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
8561*f5c631daSSadaf Ebrahimi }
8562*f5c631daSSadaf Ebrahimi 
sqsubr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)8563*f5c631daSSadaf Ebrahimi void Assembler::sqsubr(const ZRegister& zd,
8564*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
8565*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
8566*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
8567*f5c631daSSadaf Ebrahimi   // SQSUBR <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
8568*f5c631daSSadaf Ebrahimi   //  0100 0100 ..01 1110 100. .... .... ....
8569*f5c631daSSadaf Ebrahimi   //  size<23:22> | op<18> | S<17> | U<16> | Pg<12:10> | Zm<9:5> | Zdn<4:0>
8570*f5c631daSSadaf Ebrahimi 
8571*f5c631daSSadaf Ebrahimi   USE(zn);
8572*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8573*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
8574*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
8575*f5c631daSSadaf Ebrahimi 
8576*f5c631daSSadaf Ebrahimi   Emit(0x441e8000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
8577*f5c631daSSadaf Ebrahimi }
8578*f5c631daSSadaf Ebrahimi 
sqxtnb(const ZRegister & zd,const ZRegister & zn)8579*f5c631daSSadaf Ebrahimi void Assembler::sqxtnb(const ZRegister& zd, const ZRegister& zn) {
8580*f5c631daSSadaf Ebrahimi   // SQXTNB <Zd>.<T>, <Zn>.<Tb>
8581*f5c631daSSadaf Ebrahimi   //  0100 0101 0.1. .000 0100 00.. .... ....
8582*f5c631daSSadaf Ebrahimi   //  tszh<22> | tszl<20:19> | opc<12:11> | T<10> | Zn<9:5> | Zd<4:0>
8583*f5c631daSSadaf Ebrahimi 
8584*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8585*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeS() || zd.IsLaneSizeH() || zd.IsLaneSizeB());
8586*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() / 2));
8587*f5c631daSSadaf Ebrahimi 
8588*f5c631daSSadaf Ebrahimi   // XTN instructions look like immediate shifts with zero shift distance.
8589*f5c631daSSadaf Ebrahimi   Instr size = EncodeSVEShiftLeftImmediate(0, zd.GetLaneSizeInBits());
8590*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediate(zd, zn, size, 0x45204000);
8591*f5c631daSSadaf Ebrahimi }
8592*f5c631daSSadaf Ebrahimi 
sqxtnt(const ZRegister & zd,const ZRegister & zn)8593*f5c631daSSadaf Ebrahimi void Assembler::sqxtnt(const ZRegister& zd, const ZRegister& zn) {
8594*f5c631daSSadaf Ebrahimi   // SQXTNT <Zd>.<T>, <Zn>.<Tb>
8595*f5c631daSSadaf Ebrahimi   //  0100 0101 0.1. .000 0100 01.. .... ....
8596*f5c631daSSadaf Ebrahimi   //  tszh<22> | tszl<20:19> | opc<12:11> | T<10> | Zn<9:5> | Zd<4:0>
8597*f5c631daSSadaf Ebrahimi 
8598*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8599*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeS() || zd.IsLaneSizeH() || zd.IsLaneSizeB());
8600*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() / 2));
8601*f5c631daSSadaf Ebrahimi 
8602*f5c631daSSadaf Ebrahimi   // XTN instructions look like immediate shifts with zero shift distance.
8603*f5c631daSSadaf Ebrahimi   Instr size = EncodeSVEShiftLeftImmediate(0, zd.GetLaneSizeInBits());
8604*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediate(zd, zn, size, 0x45204400);
8605*f5c631daSSadaf Ebrahimi }
8606*f5c631daSSadaf Ebrahimi 
sqxtunb(const ZRegister & zd,const ZRegister & zn)8607*f5c631daSSadaf Ebrahimi void Assembler::sqxtunb(const ZRegister& zd, const ZRegister& zn) {
8608*f5c631daSSadaf Ebrahimi   // SQXTUNB <Zd>.<T>, <Zn>.<Tb>
8609*f5c631daSSadaf Ebrahimi   //  0100 0101 0.1. .000 0101 00.. .... ....
8610*f5c631daSSadaf Ebrahimi   //  tszh<22> | tszl<20:19> | opc<12:11> | T<10> | Zn<9:5> | Zd<4:0>
8611*f5c631daSSadaf Ebrahimi 
8612*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8613*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeS() || zd.IsLaneSizeH() || zd.IsLaneSizeB());
8614*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() / 2));
8615*f5c631daSSadaf Ebrahimi 
8616*f5c631daSSadaf Ebrahimi   // XTN instructions look like immediate shifts with zero shift distance.
8617*f5c631daSSadaf Ebrahimi   Instr size = EncodeSVEShiftLeftImmediate(0, zd.GetLaneSizeInBits());
8618*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediate(zd, zn, size, 0x45205000);
8619*f5c631daSSadaf Ebrahimi }
8620*f5c631daSSadaf Ebrahimi 
sqxtunt(const ZRegister & zd,const ZRegister & zn)8621*f5c631daSSadaf Ebrahimi void Assembler::sqxtunt(const ZRegister& zd, const ZRegister& zn) {
8622*f5c631daSSadaf Ebrahimi   // SQXTUNT <Zd>.<T>, <Zn>.<Tb>
8623*f5c631daSSadaf Ebrahimi   //  0100 0101 0.1. .000 0101 01.. .... ....
8624*f5c631daSSadaf Ebrahimi   //  tszh<22> | tszl<20:19> | opc<12:11> | T<10> | Zn<9:5> | Zd<4:0>
8625*f5c631daSSadaf Ebrahimi 
8626*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8627*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeS() || zd.IsLaneSizeH() || zd.IsLaneSizeB());
8628*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() / 2));
8629*f5c631daSSadaf Ebrahimi 
8630*f5c631daSSadaf Ebrahimi   // XTN instructions look like immediate shifts with zero shift distance.
8631*f5c631daSSadaf Ebrahimi   Instr size = EncodeSVEShiftLeftImmediate(0, zd.GetLaneSizeInBits());
8632*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediate(zd, zn, size, 0x45205400);
8633*f5c631daSSadaf Ebrahimi }
8634*f5c631daSSadaf Ebrahimi 
srhadd(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)8635*f5c631daSSadaf Ebrahimi void Assembler::srhadd(const ZRegister& zd,
8636*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
8637*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
8638*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
8639*f5c631daSSadaf Ebrahimi   // SRHADD <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
8640*f5c631daSSadaf Ebrahimi   //  0100 0100 ..01 0100 100. .... .... ....
8641*f5c631daSSadaf Ebrahimi   //  size<23:22> | R<18> | S<17> | U<16> | Pg<12:10> | Zm<9:5> | Zdn<4:0>
8642*f5c631daSSadaf Ebrahimi 
8643*f5c631daSSadaf Ebrahimi   USE(zn);
8644*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8645*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
8646*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
8647*f5c631daSSadaf Ebrahimi 
8648*f5c631daSSadaf Ebrahimi   Emit(0x44148000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
8649*f5c631daSSadaf Ebrahimi }
8650*f5c631daSSadaf Ebrahimi 
sri(const ZRegister & zd,const ZRegister & zn,int shift)8651*f5c631daSSadaf Ebrahimi void Assembler::sri(const ZRegister& zd, const ZRegister& zn, int shift) {
8652*f5c631daSSadaf Ebrahimi   // SRI <Zd>.<T>, <Zn>.<T>, #<const>
8653*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 1111 00.. .... ....
8654*f5c631daSSadaf Ebrahimi   //  tszh<23:22> | tszl<20:19> | imm3<18:16> | op<10> | Zn<9:5> | Zd<4:0>
8655*f5c631daSSadaf Ebrahimi 
8656*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8657*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
8658*f5c631daSSadaf Ebrahimi   Instr encoded_imm =
8659*f5c631daSSadaf Ebrahimi       EncodeSVEShiftRightImmediate(shift, zd.GetLaneSizeInBits());
8660*f5c631daSSadaf Ebrahimi 
8661*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediate(zd, zn, encoded_imm, 0x4500f000);
8662*f5c631daSSadaf Ebrahimi }
8663*f5c631daSSadaf Ebrahimi 
srshl(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)8664*f5c631daSSadaf Ebrahimi void Assembler::srshl(const ZRegister& zd,
8665*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
8666*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
8667*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
8668*f5c631daSSadaf Ebrahimi   // SRSHL <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
8669*f5c631daSSadaf Ebrahimi   //  0100 0100 ..00 0010 100. .... .... ....
8670*f5c631daSSadaf Ebrahimi   //  size<23:22> | Q<19> | R<18> | N<17> | U<16> | Pg<12:10> | Zm<9:5> |
8671*f5c631daSSadaf Ebrahimi   //  Zdn<4:0>
8672*f5c631daSSadaf Ebrahimi 
8673*f5c631daSSadaf Ebrahimi   USE(zn);
8674*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8675*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
8676*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
8677*f5c631daSSadaf Ebrahimi 
8678*f5c631daSSadaf Ebrahimi   Emit(0x44028000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
8679*f5c631daSSadaf Ebrahimi }
8680*f5c631daSSadaf Ebrahimi 
srshlr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)8681*f5c631daSSadaf Ebrahimi void Assembler::srshlr(const ZRegister& zd,
8682*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
8683*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
8684*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
8685*f5c631daSSadaf Ebrahimi   // SRSHLR <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
8686*f5c631daSSadaf Ebrahimi   //  0100 0100 ..00 0110 100. .... .... ....
8687*f5c631daSSadaf Ebrahimi   //  size<23:22> | Q<19> | R<18> | N<17> | U<16> | Pg<12:10> | Zm<9:5> |
8688*f5c631daSSadaf Ebrahimi   //  Zdn<4:0>
8689*f5c631daSSadaf Ebrahimi 
8690*f5c631daSSadaf Ebrahimi   USE(zn);
8691*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8692*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
8693*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
8694*f5c631daSSadaf Ebrahimi 
8695*f5c631daSSadaf Ebrahimi   Emit(0x44068000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
8696*f5c631daSSadaf Ebrahimi }
8697*f5c631daSSadaf Ebrahimi 
srshr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,int shift)8698*f5c631daSSadaf Ebrahimi void Assembler::srshr(const ZRegister& zd,
8699*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
8700*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
8701*f5c631daSSadaf Ebrahimi                       int shift) {
8702*f5c631daSSadaf Ebrahimi   // SRSHR <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, #<const>
8703*f5c631daSSadaf Ebrahimi   //  0000 0100 ..00 1100 100. .... .... ....
8704*f5c631daSSadaf Ebrahimi   //  tszh<23:22> | opc<19:18> | L<17> | U<16> | Pg<12:10> | tszl<9:8> |
8705*f5c631daSSadaf Ebrahimi   //  imm3<7:5> | Zdn<4:0>
8706*f5c631daSSadaf Ebrahimi 
8707*f5c631daSSadaf Ebrahimi   USE(zn);
8708*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8709*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
8710*f5c631daSSadaf Ebrahimi   Instr encoded_imm =
8711*f5c631daSSadaf Ebrahimi       EncodeSVEShiftRightImmediate(shift, zd.GetLaneSizeInBits());
8712*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediatePred(zd, pg, encoded_imm, 0x040c8000);
8713*f5c631daSSadaf Ebrahimi }
8714*f5c631daSSadaf Ebrahimi 
srsra(const ZRegister & zda,const ZRegister & zn,int shift)8715*f5c631daSSadaf Ebrahimi void Assembler::srsra(const ZRegister& zda, const ZRegister& zn, int shift) {
8716*f5c631daSSadaf Ebrahimi   // SRSRA <Zda>.<T>, <Zn>.<T>, #<const>
8717*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 1110 10.. .... ....
8718*f5c631daSSadaf Ebrahimi   //  tszh<23:22> | tszl<20:19> | imm3<18:16> | R<11> | U<10> | Zn<9:5> |
8719*f5c631daSSadaf Ebrahimi   //  Zda<4:0>
8720*f5c631daSSadaf Ebrahimi 
8721*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8722*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn));
8723*f5c631daSSadaf Ebrahimi   Instr encoded_imm =
8724*f5c631daSSadaf Ebrahimi       EncodeSVEShiftRightImmediate(shift, zda.GetLaneSizeInBits());
8725*f5c631daSSadaf Ebrahimi 
8726*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediate(zda, zn, encoded_imm, 0x4500e800);
8727*f5c631daSSadaf Ebrahimi }
8728*f5c631daSSadaf Ebrahimi 
sshllb(const ZRegister & zd,const ZRegister & zn,int shift)8729*f5c631daSSadaf Ebrahimi void Assembler::sshllb(const ZRegister& zd, const ZRegister& zn, int shift) {
8730*f5c631daSSadaf Ebrahimi   // SSHLLB <Zd>.<T>, <Zn>.<Tb>, #<const>
8731*f5c631daSSadaf Ebrahimi   //  0100 0101 0.0. .... 1010 00.. .... ....
8732*f5c631daSSadaf Ebrahimi   //  tszh<22> | tszl<20:19> | imm3<18:16> | U<11> | T<10> | Zn<9:5> | Zd<4:0>
8733*f5c631daSSadaf Ebrahimi 
8734*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8735*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zd.IsLaneSizeB());
8736*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
8737*f5c631daSSadaf Ebrahimi 
8738*f5c631daSSadaf Ebrahimi   Instr encoded_imm =
8739*f5c631daSSadaf Ebrahimi       EncodeSVEShiftLeftImmediate(shift, zn.GetLaneSizeInBits());
8740*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediate(zd, zn, encoded_imm, 0x4500a000);
8741*f5c631daSSadaf Ebrahimi }
8742*f5c631daSSadaf Ebrahimi 
sshllt(const ZRegister & zd,const ZRegister & zn,int shift)8743*f5c631daSSadaf Ebrahimi void Assembler::sshllt(const ZRegister& zd, const ZRegister& zn, int shift) {
8744*f5c631daSSadaf Ebrahimi   // SSHLLT <Zd>.<T>, <Zn>.<Tb>, #<const>
8745*f5c631daSSadaf Ebrahimi   //  0100 0101 0.0. .... 1010 01.. .... ....
8746*f5c631daSSadaf Ebrahimi   //  tszh<22> | tszl<20:19> | imm3<18:16> | U<11> | T<10> | Zn<9:5> | Zd<4:0>
8747*f5c631daSSadaf Ebrahimi 
8748*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8749*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zd.IsLaneSizeB());
8750*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
8751*f5c631daSSadaf Ebrahimi 
8752*f5c631daSSadaf Ebrahimi   Instr encoded_imm =
8753*f5c631daSSadaf Ebrahimi       EncodeSVEShiftLeftImmediate(shift, zn.GetLaneSizeInBits());
8754*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediate(zd, zn, encoded_imm, 0x4500a400);
8755*f5c631daSSadaf Ebrahimi }
8756*f5c631daSSadaf Ebrahimi 
ssra(const ZRegister & zda,const ZRegister & zn,int shift)8757*f5c631daSSadaf Ebrahimi void Assembler::ssra(const ZRegister& zda, const ZRegister& zn, int shift) {
8758*f5c631daSSadaf Ebrahimi   // SSRA <Zda>.<T>, <Zn>.<T>, #<const>
8759*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 1110 00.. .... ....
8760*f5c631daSSadaf Ebrahimi   //  tszh<23:22> | tszl<20:19> | imm3<18:16> | R<11> | U<10> | Zn<9:5> |
8761*f5c631daSSadaf Ebrahimi   //  Zda<4:0>
8762*f5c631daSSadaf Ebrahimi 
8763*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8764*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn));
8765*f5c631daSSadaf Ebrahimi   Instr encoded_imm =
8766*f5c631daSSadaf Ebrahimi       EncodeSVEShiftRightImmediate(shift, zda.GetLaneSizeInBits());
8767*f5c631daSSadaf Ebrahimi 
8768*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediate(zda, zn, encoded_imm, 0x4500e000);
8769*f5c631daSSadaf Ebrahimi }
8770*f5c631daSSadaf Ebrahimi 
ssublb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)8771*f5c631daSSadaf Ebrahimi void Assembler::ssublb(const ZRegister& zd,
8772*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
8773*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
8774*f5c631daSSadaf Ebrahimi   // SSUBLB <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
8775*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 0001 00.. .... ....
8776*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<13> | S<12> | U<11> | T<10> | Zn<9:5> |
8777*f5c631daSSadaf Ebrahimi   //  Zd<4:0>
8778*f5c631daSSadaf Ebrahimi 
8779*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8780*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
8781*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
8782*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
8783*f5c631daSSadaf Ebrahimi 
8784*f5c631daSSadaf Ebrahimi   Emit(0x45001000 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
8785*f5c631daSSadaf Ebrahimi }
8786*f5c631daSSadaf Ebrahimi 
ssublbt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)8787*f5c631daSSadaf Ebrahimi void Assembler::ssublbt(const ZRegister& zd,
8788*f5c631daSSadaf Ebrahimi                         const ZRegister& zn,
8789*f5c631daSSadaf Ebrahimi                         const ZRegister& zm) {
8790*f5c631daSSadaf Ebrahimi   // SSUBLBT <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
8791*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 1000 10.. .... ....
8792*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<11> | tb<10> | Zn<9:5> | Zd<4:0>
8793*f5c631daSSadaf Ebrahimi 
8794*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8795*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
8796*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
8797*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeD() || zd.IsLaneSizeH() || zd.IsLaneSizeS());
8798*f5c631daSSadaf Ebrahimi 
8799*f5c631daSSadaf Ebrahimi   Emit(0x45008800 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
8800*f5c631daSSadaf Ebrahimi }
8801*f5c631daSSadaf Ebrahimi 
ssublt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)8802*f5c631daSSadaf Ebrahimi void Assembler::ssublt(const ZRegister& zd,
8803*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
8804*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
8805*f5c631daSSadaf Ebrahimi   // SSUBLT <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
8806*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 0001 01.. .... ....
8807*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<13> | S<12> | U<11> | T<10> | Zn<9:5> |
8808*f5c631daSSadaf Ebrahimi   //  Zd<4:0>
8809*f5c631daSSadaf Ebrahimi 
8810*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8811*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
8812*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
8813*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
8814*f5c631daSSadaf Ebrahimi 
8815*f5c631daSSadaf Ebrahimi   Emit(0x45001400 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
8816*f5c631daSSadaf Ebrahimi }
8817*f5c631daSSadaf Ebrahimi 
ssubltb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)8818*f5c631daSSadaf Ebrahimi void Assembler::ssubltb(const ZRegister& zd,
8819*f5c631daSSadaf Ebrahimi                         const ZRegister& zn,
8820*f5c631daSSadaf Ebrahimi                         const ZRegister& zm) {
8821*f5c631daSSadaf Ebrahimi   // SSUBLTB <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
8822*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 1000 11.. .... ....
8823*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<11> | tb<10> | Zn<9:5> | Zd<4:0>
8824*f5c631daSSadaf Ebrahimi 
8825*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8826*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
8827*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
8828*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeD() || zd.IsLaneSizeH() || zd.IsLaneSizeS());
8829*f5c631daSSadaf Ebrahimi 
8830*f5c631daSSadaf Ebrahimi   Emit(0x45008c00 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
8831*f5c631daSSadaf Ebrahimi }
8832*f5c631daSSadaf Ebrahimi 
ssubwb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)8833*f5c631daSSadaf Ebrahimi void Assembler::ssubwb(const ZRegister& zd,
8834*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
8835*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
8836*f5c631daSSadaf Ebrahimi   // SSUBWB <Zd>.<T>, <Zn>.<T>, <Zm>.<Tb>
8837*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 0101 00.. .... ....
8838*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<12> | U<11> | T<10> | Zn<9:5> | Zd<4:0>
8839*f5c631daSSadaf Ebrahimi 
8840*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8841*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
8842*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zm.GetLaneSizeInBytes() * 2));
8843*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
8844*f5c631daSSadaf Ebrahimi 
8845*f5c631daSSadaf Ebrahimi   Emit(0x45005000 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
8846*f5c631daSSadaf Ebrahimi }
8847*f5c631daSSadaf Ebrahimi 
ssubwt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)8848*f5c631daSSadaf Ebrahimi void Assembler::ssubwt(const ZRegister& zd,
8849*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
8850*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
8851*f5c631daSSadaf Ebrahimi   // SSUBWT <Zd>.<T>, <Zn>.<T>, <Zm>.<Tb>
8852*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 0101 01.. .... ....
8853*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<12> | U<11> | T<10> | Zn<9:5> | Zd<4:0>
8854*f5c631daSSadaf Ebrahimi 
8855*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8856*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
8857*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zm.GetLaneSizeInBytes() * 2));
8858*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
8859*f5c631daSSadaf Ebrahimi 
8860*f5c631daSSadaf Ebrahimi   Emit(0x45005400 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
8861*f5c631daSSadaf Ebrahimi }
8862*f5c631daSSadaf Ebrahimi 
8863*f5c631daSSadaf Ebrahimi #if 0
8864*f5c631daSSadaf Ebrahimi // This prototype maps to 2 instruction encodings:
8865*f5c631daSSadaf Ebrahimi //  stnt1b_z_p_ar_d_64_unscaled
8866*f5c631daSSadaf Ebrahimi //  stnt1b_z_p_ar_s_x32_unscaled
8867*f5c631daSSadaf Ebrahimi void Assembler::stnt1b(const ZRegister& zt, const PRegister& pg, const ZRegister& zn, const Register& rm) {
8868*f5c631daSSadaf Ebrahimi   // STNT1B { <Zt>.D }, <Pg>, [<Zn>.D{, <Xm>}]
8869*f5c631daSSadaf Ebrahimi   //  1110 0100 000. .... 001. .... .... ....
8870*f5c631daSSadaf Ebrahimi   //  msz<24:23> | Rm<20:16> | Pg<12:10> | Zn<9:5> | Zt<4:0>
8871*f5c631daSSadaf Ebrahimi 
8872*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8873*f5c631daSSadaf Ebrahimi 
8874*f5c631daSSadaf Ebrahimi   Emit(0xe4002000 | Rt(zt) | PgLow8(pg) | Rn(zn) | Rm(rm));
8875*f5c631daSSadaf Ebrahimi }
8876*f5c631daSSadaf Ebrahimi 
8877*f5c631daSSadaf Ebrahimi void Assembler::stnt1d(const ZRegister& zt, const PRegister& pg, const ZRegister& zn, const Register& rm) {
8878*f5c631daSSadaf Ebrahimi   // STNT1D { <Zt>.D }, <Pg>, [<Zn>.D{, <Xm>}]
8879*f5c631daSSadaf Ebrahimi   //  1110 0101 100. .... 001. .... .... ....
8880*f5c631daSSadaf Ebrahimi   //  msz<24:23> | Rm<20:16> | Pg<12:10> | Zn<9:5> | Zt<4:0>
8881*f5c631daSSadaf Ebrahimi 
8882*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8883*f5c631daSSadaf Ebrahimi 
8884*f5c631daSSadaf Ebrahimi   Emit(0xe5802000 | Rt(zt) | PgLow8(pg) | Rn(zn) | Rm(rm));
8885*f5c631daSSadaf Ebrahimi }
8886*f5c631daSSadaf Ebrahimi 
8887*f5c631daSSadaf Ebrahimi // This prototype maps to 2 instruction encodings:
8888*f5c631daSSadaf Ebrahimi //  stnt1h_z_p_ar_d_64_unscaled
8889*f5c631daSSadaf Ebrahimi //  stnt1h_z_p_ar_s_x32_unscaled
8890*f5c631daSSadaf Ebrahimi void Assembler::stnt1h(const ZRegister& zt, const PRegister& pg, const ZRegister& zn, const Register& rm) {
8891*f5c631daSSadaf Ebrahimi   // STNT1H { <Zt>.D }, <Pg>, [<Zn>.D{, <Xm>}]
8892*f5c631daSSadaf Ebrahimi   //  1110 0100 100. .... 001. .... .... ....
8893*f5c631daSSadaf Ebrahimi   //  msz<24:23> | Rm<20:16> | Pg<12:10> | Zn<9:5> | Zt<4:0>
8894*f5c631daSSadaf Ebrahimi 
8895*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8896*f5c631daSSadaf Ebrahimi 
8897*f5c631daSSadaf Ebrahimi   Emit(0xe4802000 | Rt(zt) | PgLow8(pg) | Rn(zn) | Rm(rm));
8898*f5c631daSSadaf Ebrahimi }
8899*f5c631daSSadaf Ebrahimi 
8900*f5c631daSSadaf Ebrahimi // This prototype maps to 2 instruction encodings:
8901*f5c631daSSadaf Ebrahimi //  stnt1w_z_p_ar_d_64_unscaled
8902*f5c631daSSadaf Ebrahimi //  stnt1w_z_p_ar_s_x32_unscaled
8903*f5c631daSSadaf Ebrahimi void Assembler::stnt1w(const ZRegister& zt, const PRegister& pg, const ZRegister& zn, const Register& rm) {
8904*f5c631daSSadaf Ebrahimi   // STNT1W { <Zt>.D }, <Pg>, [<Zn>.D{, <Xm>}]
8905*f5c631daSSadaf Ebrahimi   //  1110 0101 000. .... 001. .... .... ....
8906*f5c631daSSadaf Ebrahimi   //  msz<24:23> | Rm<20:16> | Pg<12:10> | Zn<9:5> | Zt<4:0>
8907*f5c631daSSadaf Ebrahimi 
8908*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8909*f5c631daSSadaf Ebrahimi 
8910*f5c631daSSadaf Ebrahimi   Emit(0xe5002000 | Rt(zt) | PgLow8(pg) | Rn(zn) | Rm(rm));
8911*f5c631daSSadaf Ebrahimi }
8912*f5c631daSSadaf Ebrahimi #endif
8913*f5c631daSSadaf Ebrahimi 
subhnb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)8914*f5c631daSSadaf Ebrahimi void Assembler::subhnb(const ZRegister& zd,
8915*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
8916*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
8917*f5c631daSSadaf Ebrahimi   // SUBHNB <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
8918*f5c631daSSadaf Ebrahimi   //  0100 0101 ..1. .... 0111 00.. .... ....
8919*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<12> | R<11> | T<10> | Zn<9:5> | Zd<4:0>
8920*f5c631daSSadaf Ebrahimi 
8921*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8922*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
8923*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() == (zd.GetLaneSizeInBytes() * 2));
8924*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() != kBRegSizeInBytes);
8925*f5c631daSSadaf Ebrahimi 
8926*f5c631daSSadaf Ebrahimi   Emit(0x45207000 | SVESize(zn) | Rd(zd) | Rn(zn) | Rm(zm));
8927*f5c631daSSadaf Ebrahimi }
8928*f5c631daSSadaf Ebrahimi 
subhnt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)8929*f5c631daSSadaf Ebrahimi void Assembler::subhnt(const ZRegister& zd,
8930*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
8931*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
8932*f5c631daSSadaf Ebrahimi   // SUBHNT <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
8933*f5c631daSSadaf Ebrahimi   //  0100 0101 ..1. .... 0111 01.. .... ....
8934*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<12> | R<11> | T<10> | Zn<9:5> | Zd<4:0>
8935*f5c631daSSadaf Ebrahimi 
8936*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8937*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
8938*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() == (zd.GetLaneSizeInBytes() * 2));
8939*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.GetLaneSizeInBytes() != kBRegSizeInBytes);
8940*f5c631daSSadaf Ebrahimi 
8941*f5c631daSSadaf Ebrahimi   Emit(0x45207400 | SVESize(zn) | Rd(zd) | Rn(zn) | Rm(zm));
8942*f5c631daSSadaf Ebrahimi }
8943*f5c631daSSadaf Ebrahimi 
suqadd(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)8944*f5c631daSSadaf Ebrahimi void Assembler::suqadd(const ZRegister& zd,
8945*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
8946*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
8947*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
8948*f5c631daSSadaf Ebrahimi   // SUQADD <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
8949*f5c631daSSadaf Ebrahimi   //  0100 0100 ..01 1100 100. .... .... ....
8950*f5c631daSSadaf Ebrahimi   //  size<23:22> | op<18> | S<17> | U<16> | Pg<12:10> | Zm<9:5> | Zdn<4:0>
8951*f5c631daSSadaf Ebrahimi 
8952*f5c631daSSadaf Ebrahimi   USE(zn);
8953*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8954*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
8955*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
8956*f5c631daSSadaf Ebrahimi 
8957*f5c631daSSadaf Ebrahimi   Emit(0x441c8000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
8958*f5c631daSSadaf Ebrahimi }
8959*f5c631daSSadaf Ebrahimi 
tbl(const ZRegister & zd,const ZRegister & zn1,const ZRegister & zn2,const ZRegister & zm)8960*f5c631daSSadaf Ebrahimi void Assembler::tbl(const ZRegister& zd,
8961*f5c631daSSadaf Ebrahimi                     const ZRegister& zn1,
8962*f5c631daSSadaf Ebrahimi                     const ZRegister& zn2,
8963*f5c631daSSadaf Ebrahimi                     const ZRegister& zm) {
8964*f5c631daSSadaf Ebrahimi   // TBL <Zd>.<T>, { <Zn1>.<T>, <Zn2>.<T> }, <Zm>.<T>
8965*f5c631daSSadaf Ebrahimi   //  0000 0101 ..1. .... 0010 10.. .... ....
8966*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<10> | Zn<9:5> | Zd<4:0>
8967*f5c631daSSadaf Ebrahimi 
8968*f5c631daSSadaf Ebrahimi   USE(zn2);
8969*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8970*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreConsecutive(zn1, zn2));
8971*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn1, zn2, zm));
8972*f5c631daSSadaf Ebrahimi 
8973*f5c631daSSadaf Ebrahimi   Emit(0x05202800 | SVESize(zd) | Rd(zd) | Rn(zn1) | Rn(zn2) | Rm(zm));
8974*f5c631daSSadaf Ebrahimi }
8975*f5c631daSSadaf Ebrahimi 
tbx(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)8976*f5c631daSSadaf Ebrahimi void Assembler::tbx(const ZRegister& zd,
8977*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
8978*f5c631daSSadaf Ebrahimi                     const ZRegister& zm) {
8979*f5c631daSSadaf Ebrahimi   // TBX <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
8980*f5c631daSSadaf Ebrahimi   //  0000 0101 ..1. .... 0010 11.. .... ....
8981*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<10> | Zn<9:5> | Zd<4:0>
8982*f5c631daSSadaf Ebrahimi 
8983*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8984*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
8985*f5c631daSSadaf Ebrahimi 
8986*f5c631daSSadaf Ebrahimi   Emit(0x05202c00 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
8987*f5c631daSSadaf Ebrahimi }
8988*f5c631daSSadaf Ebrahimi 
uaba(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)8989*f5c631daSSadaf Ebrahimi void Assembler::uaba(const ZRegister& zda,
8990*f5c631daSSadaf Ebrahimi                      const ZRegister& zn,
8991*f5c631daSSadaf Ebrahimi                      const ZRegister& zm) {
8992*f5c631daSSadaf Ebrahimi   // UABA <Zda>.<T>, <Zn>.<T>, <Zm>.<T>
8993*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 1111 11.. .... ....
8994*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | U<10> | Zn<9:5> | Zda<4:0>
8995*f5c631daSSadaf Ebrahimi 
8996*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
8997*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn, zm));
8998*f5c631daSSadaf Ebrahimi 
8999*f5c631daSSadaf Ebrahimi   Emit(0x4500fc00 | SVESize(zda) | Rd(zda) | Rn(zn) | Rm(zm));
9000*f5c631daSSadaf Ebrahimi }
9001*f5c631daSSadaf Ebrahimi 
uabalb(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)9002*f5c631daSSadaf Ebrahimi void Assembler::uabalb(const ZRegister& zda,
9003*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
9004*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
9005*f5c631daSSadaf Ebrahimi   // UABALB <Zda>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
9006*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 1100 10.. .... ....
9007*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | U<11> | T<10> | Zn<9:5> | Zda<4:0>
9008*f5c631daSSadaf Ebrahimi 
9009*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9010*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
9011*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
9012*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() != kBRegSizeInBytes);
9013*f5c631daSSadaf Ebrahimi 
9014*f5c631daSSadaf Ebrahimi   Emit(0x4500c800 | SVESize(zda) | Rd(zda) | Rn(zn) | Rm(zm));
9015*f5c631daSSadaf Ebrahimi }
9016*f5c631daSSadaf Ebrahimi 
uabalt(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)9017*f5c631daSSadaf Ebrahimi void Assembler::uabalt(const ZRegister& zda,
9018*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
9019*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
9020*f5c631daSSadaf Ebrahimi   // UABALT <Zda>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
9021*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 1100 11.. .... ....
9022*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | U<11> | T<10> | Zn<9:5> | Zda<4:0>
9023*f5c631daSSadaf Ebrahimi 
9024*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9025*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
9026*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
9027*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() != kBRegSizeInBytes);
9028*f5c631daSSadaf Ebrahimi 
9029*f5c631daSSadaf Ebrahimi   Emit(0x4500cc00 | SVESize(zda) | Rd(zda) | Rn(zn) | Rm(zm));
9030*f5c631daSSadaf Ebrahimi }
9031*f5c631daSSadaf Ebrahimi 
uabdlb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)9032*f5c631daSSadaf Ebrahimi void Assembler::uabdlb(const ZRegister& zd,
9033*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
9034*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
9035*f5c631daSSadaf Ebrahimi   // UABDLB <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
9036*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 0011 10.. .... ....
9037*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<13> | S<12> | U<11> | T<10> | Zn<9:5> |
9038*f5c631daSSadaf Ebrahimi   //  Zd<4:0>
9039*f5c631daSSadaf Ebrahimi 
9040*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9041*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
9042*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
9043*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
9044*f5c631daSSadaf Ebrahimi 
9045*f5c631daSSadaf Ebrahimi   Emit(0x45003800 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
9046*f5c631daSSadaf Ebrahimi }
9047*f5c631daSSadaf Ebrahimi 
uabdlt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)9048*f5c631daSSadaf Ebrahimi void Assembler::uabdlt(const ZRegister& zd,
9049*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
9050*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
9051*f5c631daSSadaf Ebrahimi   // UABDLT <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
9052*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 0011 11.. .... ....
9053*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<13> | S<12> | U<11> | T<10> | Zn<9:5> |
9054*f5c631daSSadaf Ebrahimi   //  Zd<4:0>
9055*f5c631daSSadaf Ebrahimi 
9056*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9057*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
9058*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
9059*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
9060*f5c631daSSadaf Ebrahimi 
9061*f5c631daSSadaf Ebrahimi   Emit(0x45003c00 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
9062*f5c631daSSadaf Ebrahimi }
9063*f5c631daSSadaf Ebrahimi 
uadalp(const ZRegister & zda,const PRegisterM & pg,const ZRegister & zn)9064*f5c631daSSadaf Ebrahimi void Assembler::uadalp(const ZRegister& zda,
9065*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
9066*f5c631daSSadaf Ebrahimi                        const ZRegister& zn) {
9067*f5c631daSSadaf Ebrahimi   // UADALP <Zda>.<T>, <Pg>/M, <Zn>.<Tb>
9068*f5c631daSSadaf Ebrahimi   //  0100 0100 ..00 0101 101. .... .... ....
9069*f5c631daSSadaf Ebrahimi   //  size<23:22> | U<16> | Pg<12:10> | Zn<9:5> | Zda<4:0>
9070*f5c631daSSadaf Ebrahimi 
9071*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9072*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
9073*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() != kBRegSizeInBytes);
9074*f5c631daSSadaf Ebrahimi 
9075*f5c631daSSadaf Ebrahimi   Emit(0x4405a000 | SVESize(zda) | Rd(zda) | PgLow8(pg) | Rn(zn));
9076*f5c631daSSadaf Ebrahimi }
9077*f5c631daSSadaf Ebrahimi 
uaddlb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)9078*f5c631daSSadaf Ebrahimi void Assembler::uaddlb(const ZRegister& zd,
9079*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
9080*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
9081*f5c631daSSadaf Ebrahimi   // UADDLB <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
9082*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 0000 10.. .... ....
9083*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<13> | S<12> | U<11> | T<10> | Zn<9:5> |
9084*f5c631daSSadaf Ebrahimi   //  Zd<4:0>
9085*f5c631daSSadaf Ebrahimi 
9086*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9087*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
9088*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
9089*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
9090*f5c631daSSadaf Ebrahimi 
9091*f5c631daSSadaf Ebrahimi   Emit(0x45000800 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
9092*f5c631daSSadaf Ebrahimi }
9093*f5c631daSSadaf Ebrahimi 
uaddlt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)9094*f5c631daSSadaf Ebrahimi void Assembler::uaddlt(const ZRegister& zd,
9095*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
9096*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
9097*f5c631daSSadaf Ebrahimi   // UADDLT <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
9098*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 0000 11.. .... ....
9099*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<13> | S<12> | U<11> | T<10> | Zn<9:5> |
9100*f5c631daSSadaf Ebrahimi   //  Zd<4:0>
9101*f5c631daSSadaf Ebrahimi 
9102*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9103*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
9104*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
9105*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
9106*f5c631daSSadaf Ebrahimi 
9107*f5c631daSSadaf Ebrahimi   Emit(0x45000c00 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
9108*f5c631daSSadaf Ebrahimi }
9109*f5c631daSSadaf Ebrahimi 
uaddwb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)9110*f5c631daSSadaf Ebrahimi void Assembler::uaddwb(const ZRegister& zd,
9111*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
9112*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
9113*f5c631daSSadaf Ebrahimi   // UADDWB <Zd>.<T>, <Zn>.<T>, <Zm>.<Tb>
9114*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 0100 10.. .... ....
9115*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<12> | U<11> | T<10> | Zn<9:5> | Zd<4:0>
9116*f5c631daSSadaf Ebrahimi 
9117*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9118*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
9119*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zm.GetLaneSizeInBytes() * 2));
9120*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
9121*f5c631daSSadaf Ebrahimi 
9122*f5c631daSSadaf Ebrahimi   Emit(0x45004800 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
9123*f5c631daSSadaf Ebrahimi }
9124*f5c631daSSadaf Ebrahimi 
uaddwt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)9125*f5c631daSSadaf Ebrahimi void Assembler::uaddwt(const ZRegister& zd,
9126*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
9127*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
9128*f5c631daSSadaf Ebrahimi   // UADDWT <Zd>.<T>, <Zn>.<T>, <Zm>.<Tb>
9129*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 0100 11.. .... ....
9130*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<12> | U<11> | T<10> | Zn<9:5> | Zd<4:0>
9131*f5c631daSSadaf Ebrahimi 
9132*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9133*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
9134*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zm.GetLaneSizeInBytes() * 2));
9135*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
9136*f5c631daSSadaf Ebrahimi 
9137*f5c631daSSadaf Ebrahimi   Emit(0x45004c00 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
9138*f5c631daSSadaf Ebrahimi }
9139*f5c631daSSadaf Ebrahimi 
uhadd(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)9140*f5c631daSSadaf Ebrahimi void Assembler::uhadd(const ZRegister& zd,
9141*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
9142*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
9143*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
9144*f5c631daSSadaf Ebrahimi   // UHADD <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
9145*f5c631daSSadaf Ebrahimi   //  0100 0100 ..01 0001 100. .... .... ....
9146*f5c631daSSadaf Ebrahimi   //  size<23:22> | R<18> | S<17> | U<16> | Pg<12:10> | Zm<9:5> | Zdn<4:0>
9147*f5c631daSSadaf Ebrahimi 
9148*f5c631daSSadaf Ebrahimi   USE(zn);
9149*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9150*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
9151*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
9152*f5c631daSSadaf Ebrahimi 
9153*f5c631daSSadaf Ebrahimi   Emit(0x44118000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
9154*f5c631daSSadaf Ebrahimi }
9155*f5c631daSSadaf Ebrahimi 
uhsub(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)9156*f5c631daSSadaf Ebrahimi void Assembler::uhsub(const ZRegister& zd,
9157*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
9158*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
9159*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
9160*f5c631daSSadaf Ebrahimi   // UHSUB <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
9161*f5c631daSSadaf Ebrahimi   //  0100 0100 ..01 0011 100. .... .... ....
9162*f5c631daSSadaf Ebrahimi   //  size<23:22> | R<18> | S<17> | U<16> | Pg<12:10> | Zm<9:5> | Zdn<4:0>
9163*f5c631daSSadaf Ebrahimi 
9164*f5c631daSSadaf Ebrahimi   USE(zn);
9165*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9166*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
9167*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
9168*f5c631daSSadaf Ebrahimi 
9169*f5c631daSSadaf Ebrahimi   Emit(0x44138000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
9170*f5c631daSSadaf Ebrahimi }
9171*f5c631daSSadaf Ebrahimi 
uhsubr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)9172*f5c631daSSadaf Ebrahimi void Assembler::uhsubr(const ZRegister& zd,
9173*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
9174*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
9175*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
9176*f5c631daSSadaf Ebrahimi   // UHSUBR <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
9177*f5c631daSSadaf Ebrahimi   //  0100 0100 ..01 0111 100. .... .... ....
9178*f5c631daSSadaf Ebrahimi   //  size<23:22> | R<18> | S<17> | U<16> | Pg<12:10> | Zm<9:5> | Zdn<4:0>
9179*f5c631daSSadaf Ebrahimi 
9180*f5c631daSSadaf Ebrahimi   USE(zn);
9181*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9182*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
9183*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
9184*f5c631daSSadaf Ebrahimi 
9185*f5c631daSSadaf Ebrahimi   Emit(0x44178000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
9186*f5c631daSSadaf Ebrahimi }
9187*f5c631daSSadaf Ebrahimi 
umaxp(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)9188*f5c631daSSadaf Ebrahimi void Assembler::umaxp(const ZRegister& zd,
9189*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
9190*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
9191*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
9192*f5c631daSSadaf Ebrahimi   // UMAXP <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
9193*f5c631daSSadaf Ebrahimi   //  0100 0100 ..01 0101 101. .... .... ....
9194*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:17> | U<16> | Pg<12:10> | Zm<9:5> | Zdn<4:0>
9195*f5c631daSSadaf Ebrahimi 
9196*f5c631daSSadaf Ebrahimi   USE(zn);
9197*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9198*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
9199*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
9200*f5c631daSSadaf Ebrahimi 
9201*f5c631daSSadaf Ebrahimi   Emit(0x4415a000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
9202*f5c631daSSadaf Ebrahimi }
9203*f5c631daSSadaf Ebrahimi 
uminp(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)9204*f5c631daSSadaf Ebrahimi void Assembler::uminp(const ZRegister& zd,
9205*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
9206*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
9207*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
9208*f5c631daSSadaf Ebrahimi   // UMINP <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
9209*f5c631daSSadaf Ebrahimi   //  0100 0100 ..01 0111 101. .... .... ....
9210*f5c631daSSadaf Ebrahimi   //  size<23:22> | opc<18:17> | U<16> | Pg<12:10> | Zm<9:5> | Zdn<4:0>
9211*f5c631daSSadaf Ebrahimi 
9212*f5c631daSSadaf Ebrahimi   USE(zn);
9213*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9214*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
9215*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
9216*f5c631daSSadaf Ebrahimi 
9217*f5c631daSSadaf Ebrahimi   Emit(0x4417a000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
9218*f5c631daSSadaf Ebrahimi }
9219*f5c631daSSadaf Ebrahimi 
umlalb(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)9220*f5c631daSSadaf Ebrahimi void Assembler::umlalb(const ZRegister& zda,
9221*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
9222*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
9223*f5c631daSSadaf Ebrahimi   // UMLALB <Zda>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
9224*f5c631daSSadaf Ebrahimi   //  0100 0100 ..0. .... 0100 10.. .... ....
9225*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<12> | U<11> | T<10> | Zn<9:5> | Zda<4:0>
9226*f5c631daSSadaf Ebrahimi 
9227*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9228*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zda.IsLaneSizeB());
9229*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
9230*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
9231*f5c631daSSadaf Ebrahimi 
9232*f5c631daSSadaf Ebrahimi   Emit(0x44004800 | SVESize(zda) | Rd(zda) | Rn(zn) | Rm(zm));
9233*f5c631daSSadaf Ebrahimi }
9234*f5c631daSSadaf Ebrahimi 
umlalt(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)9235*f5c631daSSadaf Ebrahimi void Assembler::umlalt(const ZRegister& zda,
9236*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
9237*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
9238*f5c631daSSadaf Ebrahimi   // UMLALT <Zda>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
9239*f5c631daSSadaf Ebrahimi   //  0100 0100 ..0. .... 0100 11.. .... ....
9240*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<12> | U<11> | T<10> | Zn<9:5> | Zda<4:0>
9241*f5c631daSSadaf Ebrahimi 
9242*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9243*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zda.IsLaneSizeB());
9244*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
9245*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
9246*f5c631daSSadaf Ebrahimi 
9247*f5c631daSSadaf Ebrahimi   Emit(0x44004c00 | SVESize(zda) | Rd(zda) | Rn(zn) | Rm(zm));
9248*f5c631daSSadaf Ebrahimi }
9249*f5c631daSSadaf Ebrahimi 
umlslb(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)9250*f5c631daSSadaf Ebrahimi void Assembler::umlslb(const ZRegister& zda,
9251*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
9252*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
9253*f5c631daSSadaf Ebrahimi   // UMLSLB <Zda>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
9254*f5c631daSSadaf Ebrahimi   //  0100 0100 ..0. .... 0101 10.. .... ....
9255*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<12> | U<11> | T<10> | Zn<9:5> | Zda<4:0>
9256*f5c631daSSadaf Ebrahimi 
9257*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9258*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zda.IsLaneSizeB());
9259*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
9260*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
9261*f5c631daSSadaf Ebrahimi 
9262*f5c631daSSadaf Ebrahimi   Emit(0x44005800 | SVESize(zda) | Rd(zda) | Rn(zn) | Rm(zm));
9263*f5c631daSSadaf Ebrahimi }
9264*f5c631daSSadaf Ebrahimi 
umlslt(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)9265*f5c631daSSadaf Ebrahimi void Assembler::umlslt(const ZRegister& zda,
9266*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
9267*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
9268*f5c631daSSadaf Ebrahimi   // UMLSLT <Zda>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
9269*f5c631daSSadaf Ebrahimi   //  0100 0100 ..0. .... 0101 11.. .... ....
9270*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<12> | U<11> | T<10> | Zn<9:5> | Zda<4:0>
9271*f5c631daSSadaf Ebrahimi 
9272*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9273*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zda.IsLaneSizeB());
9274*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
9275*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
9276*f5c631daSSadaf Ebrahimi 
9277*f5c631daSSadaf Ebrahimi   Emit(0x44005c00 | SVESize(zda) | Rd(zda) | Rn(zn) | Rm(zm));
9278*f5c631daSSadaf Ebrahimi }
9279*f5c631daSSadaf Ebrahimi 
umulh(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)9280*f5c631daSSadaf Ebrahimi void Assembler::umulh(const ZRegister& zd,
9281*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
9282*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
9283*f5c631daSSadaf Ebrahimi   // UMULH <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
9284*f5c631daSSadaf Ebrahimi   //  0000 0100 ..1. .... 0110 11.. .... ....
9285*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | opc<11:10> | Zn<9:5> | Zd<4:0>
9286*f5c631daSSadaf Ebrahimi 
9287*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9288*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
9289*f5c631daSSadaf Ebrahimi 
9290*f5c631daSSadaf Ebrahimi   Emit(0x04206c00 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
9291*f5c631daSSadaf Ebrahimi }
9292*f5c631daSSadaf Ebrahimi 
umullb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)9293*f5c631daSSadaf Ebrahimi void Assembler::umullb(const ZRegister& zd,
9294*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
9295*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
9296*f5c631daSSadaf Ebrahimi   // UMULLB <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
9297*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 0111 10.. .... ....
9298*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<12> | U<11> | T<10> | Zn<9:5> | Zd<4:0>
9299*f5c631daSSadaf Ebrahimi 
9300*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9301*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
9302*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zd.IsLaneSizeB() && !zd.IsLaneSizeQ());
9303*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == zn.GetLaneSizeInBytes() * 2);
9304*f5c631daSSadaf Ebrahimi 
9305*f5c631daSSadaf Ebrahimi   Emit(0x45007800 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
9306*f5c631daSSadaf Ebrahimi }
9307*f5c631daSSadaf Ebrahimi 
umullt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)9308*f5c631daSSadaf Ebrahimi void Assembler::umullt(const ZRegister& zd,
9309*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
9310*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
9311*f5c631daSSadaf Ebrahimi   // UMULLT <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
9312*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 0111 11.. .... ....
9313*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<12> | U<11> | T<10> | Zn<9:5> | Zd<4:0>
9314*f5c631daSSadaf Ebrahimi 
9315*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9316*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
9317*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zd.IsLaneSizeB() && !zd.IsLaneSizeQ());
9318*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == zn.GetLaneSizeInBytes() * 2);
9319*f5c631daSSadaf Ebrahimi 
9320*f5c631daSSadaf Ebrahimi   Emit(0x45007c00 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
9321*f5c631daSSadaf Ebrahimi }
9322*f5c631daSSadaf Ebrahimi 
uqadd(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)9323*f5c631daSSadaf Ebrahimi void Assembler::uqadd(const ZRegister& zd,
9324*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
9325*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
9326*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
9327*f5c631daSSadaf Ebrahimi   // UQADD <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
9328*f5c631daSSadaf Ebrahimi   //  0100 0100 ..01 1001 100. .... .... ....
9329*f5c631daSSadaf Ebrahimi   //  size<23:22> | op<18> | S<17> | U<16> | Pg<12:10> | Zm<9:5> | Zdn<4:0>
9330*f5c631daSSadaf Ebrahimi 
9331*f5c631daSSadaf Ebrahimi   USE(zn);
9332*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9333*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
9334*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
9335*f5c631daSSadaf Ebrahimi 
9336*f5c631daSSadaf Ebrahimi   Emit(0x44198000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
9337*f5c631daSSadaf Ebrahimi }
9338*f5c631daSSadaf Ebrahimi 
uqrshl(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)9339*f5c631daSSadaf Ebrahimi void Assembler::uqrshl(const ZRegister& zd,
9340*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
9341*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
9342*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
9343*f5c631daSSadaf Ebrahimi   // UQRSHL <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
9344*f5c631daSSadaf Ebrahimi   //  0100 0100 ..00 1011 100. .... .... ....
9345*f5c631daSSadaf Ebrahimi   //  size<23:22> | Q<19> | R<18> | N<17> | U<16> | Pg<12:10> | Zm<9:5> |
9346*f5c631daSSadaf Ebrahimi   //  Zdn<4:0>
9347*f5c631daSSadaf Ebrahimi 
9348*f5c631daSSadaf Ebrahimi   USE(zn);
9349*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9350*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
9351*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
9352*f5c631daSSadaf Ebrahimi 
9353*f5c631daSSadaf Ebrahimi   Emit(0x440b8000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
9354*f5c631daSSadaf Ebrahimi }
9355*f5c631daSSadaf Ebrahimi 
uqrshlr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)9356*f5c631daSSadaf Ebrahimi void Assembler::uqrshlr(const ZRegister& zd,
9357*f5c631daSSadaf Ebrahimi                         const PRegisterM& pg,
9358*f5c631daSSadaf Ebrahimi                         const ZRegister& zn,
9359*f5c631daSSadaf Ebrahimi                         const ZRegister& zm) {
9360*f5c631daSSadaf Ebrahimi   // UQRSHLR <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
9361*f5c631daSSadaf Ebrahimi   //  0100 0100 ..00 1111 100. .... .... ....
9362*f5c631daSSadaf Ebrahimi   //  size<23:22> | Q<19> | R<18> | N<17> | U<16> | Pg<12:10> | Zm<9:5> |
9363*f5c631daSSadaf Ebrahimi   //  Zdn<4:0>
9364*f5c631daSSadaf Ebrahimi 
9365*f5c631daSSadaf Ebrahimi   USE(zn);
9366*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9367*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
9368*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
9369*f5c631daSSadaf Ebrahimi 
9370*f5c631daSSadaf Ebrahimi   Emit(0x440f8000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
9371*f5c631daSSadaf Ebrahimi }
9372*f5c631daSSadaf Ebrahimi 
uqshl(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,int shift)9373*f5c631daSSadaf Ebrahimi void Assembler::uqshl(const ZRegister& zd,
9374*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
9375*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
9376*f5c631daSSadaf Ebrahimi                       int shift) {
9377*f5c631daSSadaf Ebrahimi   // UQSHL <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, #<const>
9378*f5c631daSSadaf Ebrahimi   //  0000 0100 ..00 0111 100. .... .... ....
9379*f5c631daSSadaf Ebrahimi   //  tszh<23:22> | opc<19:18> | L<17> | U<16> | Pg<12:10> | tszl<9:8> |
9380*f5c631daSSadaf Ebrahimi   //  imm3<7:5> | Zdn<4:0>
9381*f5c631daSSadaf Ebrahimi 
9382*f5c631daSSadaf Ebrahimi   USE(zn);
9383*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9384*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
9385*f5c631daSSadaf Ebrahimi   Instr encoded_imm =
9386*f5c631daSSadaf Ebrahimi       EncodeSVEShiftLeftImmediate(shift, zd.GetLaneSizeInBits());
9387*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediatePred(zd, pg, encoded_imm, 0x04078000);
9388*f5c631daSSadaf Ebrahimi }
9389*f5c631daSSadaf Ebrahimi 
uqshl(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)9390*f5c631daSSadaf Ebrahimi void Assembler::uqshl(const ZRegister& zd,
9391*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
9392*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
9393*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
9394*f5c631daSSadaf Ebrahimi   // UQSHL <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
9395*f5c631daSSadaf Ebrahimi   //  0100 0100 ..00 1001 100. .... .... ....
9396*f5c631daSSadaf Ebrahimi   //  size<23:22> | Q<19> | R<18> | N<17> | U<16> | Pg<12:10> | Zm<9:5> |
9397*f5c631daSSadaf Ebrahimi   //  Zdn<4:0>
9398*f5c631daSSadaf Ebrahimi 
9399*f5c631daSSadaf Ebrahimi   USE(zn);
9400*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9401*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
9402*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
9403*f5c631daSSadaf Ebrahimi 
9404*f5c631daSSadaf Ebrahimi   Emit(0x44098000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
9405*f5c631daSSadaf Ebrahimi }
9406*f5c631daSSadaf Ebrahimi 
uqshlr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)9407*f5c631daSSadaf Ebrahimi void Assembler::uqshlr(const ZRegister& zd,
9408*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
9409*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
9410*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
9411*f5c631daSSadaf Ebrahimi   // UQSHLR <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
9412*f5c631daSSadaf Ebrahimi   //  0100 0100 ..00 1101 100. .... .... ....
9413*f5c631daSSadaf Ebrahimi   //  size<23:22> | Q<19> | R<18> | N<17> | U<16> | Pg<12:10> | Zm<9:5> |
9414*f5c631daSSadaf Ebrahimi   //  Zdn<4:0>
9415*f5c631daSSadaf Ebrahimi 
9416*f5c631daSSadaf Ebrahimi   USE(zn);
9417*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9418*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
9419*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
9420*f5c631daSSadaf Ebrahimi 
9421*f5c631daSSadaf Ebrahimi   Emit(0x440d8000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
9422*f5c631daSSadaf Ebrahimi }
9423*f5c631daSSadaf Ebrahimi 
uqsub(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)9424*f5c631daSSadaf Ebrahimi void Assembler::uqsub(const ZRegister& zd,
9425*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
9426*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
9427*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
9428*f5c631daSSadaf Ebrahimi   // UQSUB <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
9429*f5c631daSSadaf Ebrahimi   //  0100 0100 ..01 1011 100. .... .... ....
9430*f5c631daSSadaf Ebrahimi   //  size<23:22> | op<18> | S<17> | U<16> | Pg<12:10> | Zm<9:5> | Zdn<4:0>
9431*f5c631daSSadaf Ebrahimi 
9432*f5c631daSSadaf Ebrahimi   USE(zn);
9433*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9434*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
9435*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
9436*f5c631daSSadaf Ebrahimi 
9437*f5c631daSSadaf Ebrahimi   Emit(0x441b8000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
9438*f5c631daSSadaf Ebrahimi }
9439*f5c631daSSadaf Ebrahimi 
uqsubr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)9440*f5c631daSSadaf Ebrahimi void Assembler::uqsubr(const ZRegister& zd,
9441*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
9442*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
9443*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
9444*f5c631daSSadaf Ebrahimi   // UQSUBR <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
9445*f5c631daSSadaf Ebrahimi   //  0100 0100 ..01 1111 100. .... .... ....
9446*f5c631daSSadaf Ebrahimi   //  size<23:22> | op<18> | S<17> | U<16> | Pg<12:10> | Zm<9:5> | Zdn<4:0>
9447*f5c631daSSadaf Ebrahimi 
9448*f5c631daSSadaf Ebrahimi   USE(zn);
9449*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9450*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
9451*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
9452*f5c631daSSadaf Ebrahimi 
9453*f5c631daSSadaf Ebrahimi   Emit(0x441f8000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
9454*f5c631daSSadaf Ebrahimi }
9455*f5c631daSSadaf Ebrahimi 
uqxtnb(const ZRegister & zd,const ZRegister & zn)9456*f5c631daSSadaf Ebrahimi void Assembler::uqxtnb(const ZRegister& zd, const ZRegister& zn) {
9457*f5c631daSSadaf Ebrahimi   // UQXTNB <Zd>.<T>, <Zn>.<Tb>
9458*f5c631daSSadaf Ebrahimi   //  0100 0101 0.1. .000 0100 10.. .... ....
9459*f5c631daSSadaf Ebrahimi   //  tszh<22> | tszl<20:19> | opc<12:11> | T<10> | Zn<9:5> | Zd<4:0>
9460*f5c631daSSadaf Ebrahimi 
9461*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9462*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeS() || zd.IsLaneSizeH() || zd.IsLaneSizeB());
9463*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() / 2));
9464*f5c631daSSadaf Ebrahimi 
9465*f5c631daSSadaf Ebrahimi   // XTN instructions look like immediate shifts with zero shift distance.
9466*f5c631daSSadaf Ebrahimi   Instr size = EncodeSVEShiftLeftImmediate(0, zd.GetLaneSizeInBits());
9467*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediate(zd, zn, size, 0x45204800);
9468*f5c631daSSadaf Ebrahimi }
9469*f5c631daSSadaf Ebrahimi 
uqxtnt(const ZRegister & zd,const ZRegister & zn)9470*f5c631daSSadaf Ebrahimi void Assembler::uqxtnt(const ZRegister& zd, const ZRegister& zn) {
9471*f5c631daSSadaf Ebrahimi   // UQXTNT <Zd>.<T>, <Zn>.<Tb>
9472*f5c631daSSadaf Ebrahimi   //  0100 0101 0.1. .000 0100 11.. .... ....
9473*f5c631daSSadaf Ebrahimi   //  tszh<22> | tszl<20:19> | opc<12:11> | T<10> | Zn<9:5> | Zd<4:0>
9474*f5c631daSSadaf Ebrahimi 
9475*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9476*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeS() || zd.IsLaneSizeH() || zd.IsLaneSizeB());
9477*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() / 2));
9478*f5c631daSSadaf Ebrahimi 
9479*f5c631daSSadaf Ebrahimi   // XTN instructions look like immediate shifts with zero shift distance.
9480*f5c631daSSadaf Ebrahimi   Instr size = EncodeSVEShiftLeftImmediate(0, zd.GetLaneSizeInBits());
9481*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediate(zd, zn, size, 0x45204c00);
9482*f5c631daSSadaf Ebrahimi }
9483*f5c631daSSadaf Ebrahimi 
urecpe(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)9484*f5c631daSSadaf Ebrahimi void Assembler::urecpe(const ZRegister& zd,
9485*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
9486*f5c631daSSadaf Ebrahimi                        const ZRegister& zn) {
9487*f5c631daSSadaf Ebrahimi   // URECPE <Zd>.S, <Pg>/M, <Zn>.S
9488*f5c631daSSadaf Ebrahimi   //  0100 0100 ..00 0000 101. .... .... ....
9489*f5c631daSSadaf Ebrahimi   //  size<23:22> | Q<19> | opc<17:16> | Pg<12:10> | Zn<9:5> | Zd<4:0>
9490*f5c631daSSadaf Ebrahimi 
9491*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9492*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeS() && zn.IsLaneSizeS());
9493*f5c631daSSadaf Ebrahimi 
9494*f5c631daSSadaf Ebrahimi   Emit(0x4400a000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
9495*f5c631daSSadaf Ebrahimi }
9496*f5c631daSSadaf Ebrahimi 
urhadd(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)9497*f5c631daSSadaf Ebrahimi void Assembler::urhadd(const ZRegister& zd,
9498*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
9499*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
9500*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
9501*f5c631daSSadaf Ebrahimi   // URHADD <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
9502*f5c631daSSadaf Ebrahimi   //  0100 0100 ..01 0101 100. .... .... ....
9503*f5c631daSSadaf Ebrahimi   //  size<23:22> | R<18> | S<17> | U<16> | Pg<12:10> | Zm<9:5> | Zdn<4:0>
9504*f5c631daSSadaf Ebrahimi 
9505*f5c631daSSadaf Ebrahimi   USE(zn);
9506*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9507*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
9508*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
9509*f5c631daSSadaf Ebrahimi 
9510*f5c631daSSadaf Ebrahimi   Emit(0x44158000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
9511*f5c631daSSadaf Ebrahimi }
9512*f5c631daSSadaf Ebrahimi 
urshl(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)9513*f5c631daSSadaf Ebrahimi void Assembler::urshl(const ZRegister& zd,
9514*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
9515*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
9516*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
9517*f5c631daSSadaf Ebrahimi   // URSHL <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
9518*f5c631daSSadaf Ebrahimi   //  0100 0100 ..00 0011 100. .... .... ....
9519*f5c631daSSadaf Ebrahimi   //  size<23:22> | Q<19> | R<18> | N<17> | U<16> | Pg<12:10> | Zm<9:5> |
9520*f5c631daSSadaf Ebrahimi   //  Zdn<4:0>
9521*f5c631daSSadaf Ebrahimi 
9522*f5c631daSSadaf Ebrahimi   USE(zn);
9523*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9524*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
9525*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
9526*f5c631daSSadaf Ebrahimi 
9527*f5c631daSSadaf Ebrahimi   Emit(0x44038000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
9528*f5c631daSSadaf Ebrahimi }
9529*f5c631daSSadaf Ebrahimi 
urshlr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)9530*f5c631daSSadaf Ebrahimi void Assembler::urshlr(const ZRegister& zd,
9531*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
9532*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
9533*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
9534*f5c631daSSadaf Ebrahimi   // URSHLR <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
9535*f5c631daSSadaf Ebrahimi   //  0100 0100 ..00 0111 100. .... .... ....
9536*f5c631daSSadaf Ebrahimi   //  size<23:22> | Q<19> | R<18> | N<17> | U<16> | Pg<12:10> | Zm<9:5> |
9537*f5c631daSSadaf Ebrahimi   //  Zdn<4:0>
9538*f5c631daSSadaf Ebrahimi 
9539*f5c631daSSadaf Ebrahimi   USE(zn);
9540*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9541*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
9542*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
9543*f5c631daSSadaf Ebrahimi 
9544*f5c631daSSadaf Ebrahimi   Emit(0x44078000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
9545*f5c631daSSadaf Ebrahimi }
9546*f5c631daSSadaf Ebrahimi 
urshr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,int shift)9547*f5c631daSSadaf Ebrahimi void Assembler::urshr(const ZRegister& zd,
9548*f5c631daSSadaf Ebrahimi                       const PRegisterM& pg,
9549*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
9550*f5c631daSSadaf Ebrahimi                       int shift) {
9551*f5c631daSSadaf Ebrahimi   // URSHR <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, #<const>
9552*f5c631daSSadaf Ebrahimi   //  0000 0100 ..00 1101 100. .... .... ....
9553*f5c631daSSadaf Ebrahimi   //  tszh<23:22> | opc<19:18> | L<17> | U<16> | Pg<12:10> | tszl<9:8> |
9554*f5c631daSSadaf Ebrahimi   //  imm3<7:5> | Zdn<4:0>
9555*f5c631daSSadaf Ebrahimi 
9556*f5c631daSSadaf Ebrahimi   USE(zn);
9557*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9558*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
9559*f5c631daSSadaf Ebrahimi   Instr encoded_imm =
9560*f5c631daSSadaf Ebrahimi       EncodeSVEShiftRightImmediate(shift, zd.GetLaneSizeInBits());
9561*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediatePred(zd, pg, encoded_imm, 0x040d8000);
9562*f5c631daSSadaf Ebrahimi }
9563*f5c631daSSadaf Ebrahimi 
ursqrte(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)9564*f5c631daSSadaf Ebrahimi void Assembler::ursqrte(const ZRegister& zd,
9565*f5c631daSSadaf Ebrahimi                         const PRegisterM& pg,
9566*f5c631daSSadaf Ebrahimi                         const ZRegister& zn) {
9567*f5c631daSSadaf Ebrahimi   // URSQRTE <Zd>.S, <Pg>/M, <Zn>.S
9568*f5c631daSSadaf Ebrahimi   //  0100 0100 ..00 0001 101. .... .... ....
9569*f5c631daSSadaf Ebrahimi   //  size<23:22> | Q<19> | opc<17:16> | Pg<12:10> | Zn<9:5> | Zd<4:0>
9570*f5c631daSSadaf Ebrahimi 
9571*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9572*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.IsLaneSizeS() && zn.IsLaneSizeS());
9573*f5c631daSSadaf Ebrahimi 
9574*f5c631daSSadaf Ebrahimi   Emit(0x4401a000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zn));
9575*f5c631daSSadaf Ebrahimi }
9576*f5c631daSSadaf Ebrahimi 
ursra(const ZRegister & zda,const ZRegister & zn,int shift)9577*f5c631daSSadaf Ebrahimi void Assembler::ursra(const ZRegister& zda, const ZRegister& zn, int shift) {
9578*f5c631daSSadaf Ebrahimi   // URSRA <Zda>.<T>, <Zn>.<T>, #<const>
9579*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 1110 11.. .... ....
9580*f5c631daSSadaf Ebrahimi   //  tszh<23:22> | tszl<20:19> | imm3<18:16> | R<11> | U<10> | Zn<9:5> |
9581*f5c631daSSadaf Ebrahimi   //  Zda<4:0>
9582*f5c631daSSadaf Ebrahimi 
9583*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9584*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn));
9585*f5c631daSSadaf Ebrahimi   Instr encoded_imm =
9586*f5c631daSSadaf Ebrahimi       EncodeSVEShiftRightImmediate(shift, zda.GetLaneSizeInBits());
9587*f5c631daSSadaf Ebrahimi 
9588*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediate(zda, zn, encoded_imm, 0x4500ec00);
9589*f5c631daSSadaf Ebrahimi }
9590*f5c631daSSadaf Ebrahimi 
ushllb(const ZRegister & zd,const ZRegister & zn,int shift)9591*f5c631daSSadaf Ebrahimi void Assembler::ushllb(const ZRegister& zd, const ZRegister& zn, int shift) {
9592*f5c631daSSadaf Ebrahimi   // USHLLB <Zd>.<T>, <Zn>.<Tb>, #<const>
9593*f5c631daSSadaf Ebrahimi   //  0100 0101 0.0. .... 1010 10.. .... ....
9594*f5c631daSSadaf Ebrahimi   //  tszh<22> | tszl<20:19> | imm3<18:16> | U<11> | T<10> | Zn<9:5> | Zd<4:0>
9595*f5c631daSSadaf Ebrahimi 
9596*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9597*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zd.IsLaneSizeB());
9598*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
9599*f5c631daSSadaf Ebrahimi 
9600*f5c631daSSadaf Ebrahimi   Instr encoded_imm =
9601*f5c631daSSadaf Ebrahimi       EncodeSVEShiftLeftImmediate(shift, zn.GetLaneSizeInBits());
9602*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediate(zd, zn, encoded_imm, 0x4500a800);
9603*f5c631daSSadaf Ebrahimi }
9604*f5c631daSSadaf Ebrahimi 
ushllt(const ZRegister & zd,const ZRegister & zn,int shift)9605*f5c631daSSadaf Ebrahimi void Assembler::ushllt(const ZRegister& zd, const ZRegister& zn, int shift) {
9606*f5c631daSSadaf Ebrahimi   // USHLLT <Zd>.<T>, <Zn>.<Tb>, #<const>
9607*f5c631daSSadaf Ebrahimi   //  0100 0101 0.0. .... 1010 11.. .... ....
9608*f5c631daSSadaf Ebrahimi   //  tszh<22> | tszl<20:19> | imm3<18:16> | U<11> | T<10> | Zn<9:5> | Zd<4:0>
9609*f5c631daSSadaf Ebrahimi 
9610*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9611*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(!zd.IsLaneSizeB());
9612*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
9613*f5c631daSSadaf Ebrahimi 
9614*f5c631daSSadaf Ebrahimi   Instr encoded_imm =
9615*f5c631daSSadaf Ebrahimi       EncodeSVEShiftLeftImmediate(shift, zn.GetLaneSizeInBits());
9616*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediate(zd, zn, encoded_imm, 0x4500ac00);
9617*f5c631daSSadaf Ebrahimi }
9618*f5c631daSSadaf Ebrahimi 
usqadd(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,const ZRegister & zm)9619*f5c631daSSadaf Ebrahimi void Assembler::usqadd(const ZRegister& zd,
9620*f5c631daSSadaf Ebrahimi                        const PRegisterM& pg,
9621*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
9622*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
9623*f5c631daSSadaf Ebrahimi   // USQADD <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>
9624*f5c631daSSadaf Ebrahimi   //  0100 0100 ..01 1101 100. .... .... ....
9625*f5c631daSSadaf Ebrahimi   //  size<23:22> | op<18> | S<17> | U<16> | Pg<12:10> | Zm<9:5> | Zdn<4:0>
9626*f5c631daSSadaf Ebrahimi 
9627*f5c631daSSadaf Ebrahimi   USE(zn);
9628*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9629*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
9630*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
9631*f5c631daSSadaf Ebrahimi 
9632*f5c631daSSadaf Ebrahimi   Emit(0x441d8000 | SVESize(zd) | Rd(zd) | PgLow8(pg) | Rn(zm));
9633*f5c631daSSadaf Ebrahimi }
9634*f5c631daSSadaf Ebrahimi 
usra(const ZRegister & zda,const ZRegister & zn,int shift)9635*f5c631daSSadaf Ebrahimi void Assembler::usra(const ZRegister& zda, const ZRegister& zn, int shift) {
9636*f5c631daSSadaf Ebrahimi   // USRA <Zda>.<T>, <Zn>.<T>, #<const>
9637*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 1110 01.. .... ....
9638*f5c631daSSadaf Ebrahimi   //  tszh<23:22> | tszl<20:19> | imm3<18:16> | R<11> | U<10> | Zn<9:5> |
9639*f5c631daSSadaf Ebrahimi   //  Zda<4:0>
9640*f5c631daSSadaf Ebrahimi 
9641*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9642*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn));
9643*f5c631daSSadaf Ebrahimi   Instr encoded_imm =
9644*f5c631daSSadaf Ebrahimi       EncodeSVEShiftRightImmediate(shift, zda.GetLaneSizeInBits());
9645*f5c631daSSadaf Ebrahimi 
9646*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediate(zda, zn, encoded_imm, 0x4500e400);
9647*f5c631daSSadaf Ebrahimi }
9648*f5c631daSSadaf Ebrahimi 
usublb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)9649*f5c631daSSadaf Ebrahimi void Assembler::usublb(const ZRegister& zd,
9650*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
9651*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
9652*f5c631daSSadaf Ebrahimi   // USUBLB <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
9653*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 0001 10.. .... ....
9654*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<13> | S<12> | U<11> | T<10> | Zn<9:5> |
9655*f5c631daSSadaf Ebrahimi   //  Zd<4:0>
9656*f5c631daSSadaf Ebrahimi 
9657*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9658*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
9659*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
9660*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
9661*f5c631daSSadaf Ebrahimi 
9662*f5c631daSSadaf Ebrahimi   Emit(0x45001800 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
9663*f5c631daSSadaf Ebrahimi }
9664*f5c631daSSadaf Ebrahimi 
usublt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)9665*f5c631daSSadaf Ebrahimi void Assembler::usublt(const ZRegister& zd,
9666*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
9667*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
9668*f5c631daSSadaf Ebrahimi   // USUBLT <Zd>.<T>, <Zn>.<Tb>, <Zm>.<Tb>
9669*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 0001 11.. .... ....
9670*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | op<13> | S<12> | U<11> | T<10> | Zn<9:5> |
9671*f5c631daSSadaf Ebrahimi   //  Zd<4:0>
9672*f5c631daSSadaf Ebrahimi 
9673*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9674*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zn, zm));
9675*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zn.GetLaneSizeInBytes() * 2));
9676*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
9677*f5c631daSSadaf Ebrahimi 
9678*f5c631daSSadaf Ebrahimi   Emit(0x45001c00 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
9679*f5c631daSSadaf Ebrahimi }
9680*f5c631daSSadaf Ebrahimi 
usubwb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)9681*f5c631daSSadaf Ebrahimi void Assembler::usubwb(const ZRegister& zd,
9682*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
9683*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
9684*f5c631daSSadaf Ebrahimi   // USUBWB <Zd>.<T>, <Zn>.<T>, <Zm>.<Tb>
9685*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 0101 10.. .... ....
9686*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<12> | U<11> | T<10> | Zn<9:5> | Zd<4:0>
9687*f5c631daSSadaf Ebrahimi 
9688*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9689*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
9690*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zm.GetLaneSizeInBytes() * 2));
9691*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
9692*f5c631daSSadaf Ebrahimi 
9693*f5c631daSSadaf Ebrahimi   Emit(0x45005800 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
9694*f5c631daSSadaf Ebrahimi }
9695*f5c631daSSadaf Ebrahimi 
usubwt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)9696*f5c631daSSadaf Ebrahimi void Assembler::usubwt(const ZRegister& zd,
9697*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
9698*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
9699*f5c631daSSadaf Ebrahimi   // USUBWT <Zd>.<T>, <Zn>.<T>, <Zm>.<Tb>
9700*f5c631daSSadaf Ebrahimi   //  0100 0101 ..0. .... 0101 11.. .... ....
9701*f5c631daSSadaf Ebrahimi   //  size<23:22> | Zm<20:16> | S<12> | U<11> | T<10> | Zn<9:5> | Zd<4:0>
9702*f5c631daSSadaf Ebrahimi 
9703*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9704*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zn));
9705*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() == (zm.GetLaneSizeInBytes() * 2));
9706*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.GetLaneSizeInBytes() != kBRegSizeInBytes);
9707*f5c631daSSadaf Ebrahimi 
9708*f5c631daSSadaf Ebrahimi   Emit(0x45005c00 | SVESize(zd) | Rd(zd) | Rn(zn) | Rm(zm));
9709*f5c631daSSadaf Ebrahimi }
9710*f5c631daSSadaf Ebrahimi 
whilege(const PRegisterWithLaneSize & pd,const Register & rn,const Register & rm)9711*f5c631daSSadaf Ebrahimi void Assembler::whilege(const PRegisterWithLaneSize& pd,
9712*f5c631daSSadaf Ebrahimi                         const Register& rn,
9713*f5c631daSSadaf Ebrahimi                         const Register& rm) {
9714*f5c631daSSadaf Ebrahimi   // WHILEGE <Pd>.<T>, <R><n>, <R><m>
9715*f5c631daSSadaf Ebrahimi   //  0010 0101 ..1. .... 000. 00.. ...0 ....
9716*f5c631daSSadaf Ebrahimi   //  size<23:22> | Rm<20:16> | sf<12> | U<11> | lt<10> | Rn<9:5> | eq<4> |
9717*f5c631daSSadaf Ebrahimi   //  Pd<3:0>
9718*f5c631daSSadaf Ebrahimi 
9719*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9720*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameSizeAndType(rn, rm));
9721*f5c631daSSadaf Ebrahimi   const Instr sf = rn.Is64Bits() ? 0x00001000 : 0x00000000;
9722*f5c631daSSadaf Ebrahimi 
9723*f5c631daSSadaf Ebrahimi   Emit(0x25200000 | SVESize(pd) | sf | Pd(pd) | Rn(rn) | Rm(rm));
9724*f5c631daSSadaf Ebrahimi }
9725*f5c631daSSadaf Ebrahimi 
whilegt(const PRegisterWithLaneSize & pd,const Register & rn,const Register & rm)9726*f5c631daSSadaf Ebrahimi void Assembler::whilegt(const PRegisterWithLaneSize& pd,
9727*f5c631daSSadaf Ebrahimi                         const Register& rn,
9728*f5c631daSSadaf Ebrahimi                         const Register& rm) {
9729*f5c631daSSadaf Ebrahimi   // WHILEGT <Pd>.<T>, <R><n>, <R><m>
9730*f5c631daSSadaf Ebrahimi   //  0010 0101 ..1. .... 000. 00.. ...1 ....
9731*f5c631daSSadaf Ebrahimi   //  size<23:22> | Rm<20:16> | sf<12> | U<11> | lt<10> | Rn<9:5> | eq<4> |
9732*f5c631daSSadaf Ebrahimi   //  Pd<3:0>
9733*f5c631daSSadaf Ebrahimi 
9734*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9735*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameSizeAndType(rn, rm));
9736*f5c631daSSadaf Ebrahimi   const Instr sf = rn.Is64Bits() ? 0x00001000 : 0x00000000;
9737*f5c631daSSadaf Ebrahimi 
9738*f5c631daSSadaf Ebrahimi   Emit(0x25200010 | SVESize(pd) | sf | Pd(pd) | Rn(rn) | Rm(rm));
9739*f5c631daSSadaf Ebrahimi }
9740*f5c631daSSadaf Ebrahimi 
whilehi(const PRegisterWithLaneSize & pd,const Register & rn,const Register & rm)9741*f5c631daSSadaf Ebrahimi void Assembler::whilehi(const PRegisterWithLaneSize& pd,
9742*f5c631daSSadaf Ebrahimi                         const Register& rn,
9743*f5c631daSSadaf Ebrahimi                         const Register& rm) {
9744*f5c631daSSadaf Ebrahimi   // WHILEHI <Pd>.<T>, <R><n>, <R><m>
9745*f5c631daSSadaf Ebrahimi   //  0010 0101 ..1. .... 000. 10.. ...1 ....
9746*f5c631daSSadaf Ebrahimi   //  size<23:22> | Rm<20:16> | sf<12> | U<11> | lt<10> | Rn<9:5> | eq<4> |
9747*f5c631daSSadaf Ebrahimi   //  Pd<3:0>
9748*f5c631daSSadaf Ebrahimi 
9749*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9750*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameSizeAndType(rn, rm));
9751*f5c631daSSadaf Ebrahimi   const Instr sf = rn.Is64Bits() ? 0x00001000 : 0x00000000;
9752*f5c631daSSadaf Ebrahimi 
9753*f5c631daSSadaf Ebrahimi   Emit(0x25200810 | SVESize(pd) | sf | Pd(pd) | Rn(rn) | Rm(rm));
9754*f5c631daSSadaf Ebrahimi }
9755*f5c631daSSadaf Ebrahimi 
whilehs(const PRegisterWithLaneSize & pd,const Register & rn,const Register & rm)9756*f5c631daSSadaf Ebrahimi void Assembler::whilehs(const PRegisterWithLaneSize& pd,
9757*f5c631daSSadaf Ebrahimi                         const Register& rn,
9758*f5c631daSSadaf Ebrahimi                         const Register& rm) {
9759*f5c631daSSadaf Ebrahimi   // WHILEHS <Pd>.<T>, <R><n>, <R><m>
9760*f5c631daSSadaf Ebrahimi   //  0010 0101 ..1. .... 000. 10.. ...0 ....
9761*f5c631daSSadaf Ebrahimi   //  size<23:22> | Rm<20:16> | sf<12> | U<11> | lt<10> | Rn<9:5> | eq<4> |
9762*f5c631daSSadaf Ebrahimi   //  Pd<3:0>
9763*f5c631daSSadaf Ebrahimi 
9764*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9765*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameSizeAndType(rn, rm));
9766*f5c631daSSadaf Ebrahimi   const Instr sf = rn.Is64Bits() ? 0x00001000 : 0x00000000;
9767*f5c631daSSadaf Ebrahimi 
9768*f5c631daSSadaf Ebrahimi   Emit(0x25200800 | SVESize(pd) | sf | Pd(pd) | Rn(rn) | Rm(rm));
9769*f5c631daSSadaf Ebrahimi }
9770*f5c631daSSadaf Ebrahimi 
whilerw(const PRegisterWithLaneSize & pd,const Register & rn,const Register & rm)9771*f5c631daSSadaf Ebrahimi void Assembler::whilerw(const PRegisterWithLaneSize& pd,
9772*f5c631daSSadaf Ebrahimi                         const Register& rn,
9773*f5c631daSSadaf Ebrahimi                         const Register& rm) {
9774*f5c631daSSadaf Ebrahimi   // WHILERW <Pd>.<T>, <Xn>, <Xm>
9775*f5c631daSSadaf Ebrahimi   //  0010 0101 ..1. .... 0011 00.. ...1 ....
9776*f5c631daSSadaf Ebrahimi   //  size<23:22> | Rm<20:16> | Rn<9:5> | rw<4> | Pd<3:0>
9777*f5c631daSSadaf Ebrahimi 
9778*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9779*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(rn.IsX() && rm.IsX());
9780*f5c631daSSadaf Ebrahimi 
9781*f5c631daSSadaf Ebrahimi   Emit(0x25203010 | SVESize(pd) | Pd(pd) | Rn(rn) | Rm(rm));
9782*f5c631daSSadaf Ebrahimi }
9783*f5c631daSSadaf Ebrahimi 
whilewr(const PRegisterWithLaneSize & pd,const Register & rn,const Register & rm)9784*f5c631daSSadaf Ebrahimi void Assembler::whilewr(const PRegisterWithLaneSize& pd,
9785*f5c631daSSadaf Ebrahimi                         const Register& rn,
9786*f5c631daSSadaf Ebrahimi                         const Register& rm) {
9787*f5c631daSSadaf Ebrahimi   // WHILEWR <Pd>.<T>, <Xn>, <Xm>
9788*f5c631daSSadaf Ebrahimi   //  0010 0101 ..1. .... 0011 00.. ...0 ....
9789*f5c631daSSadaf Ebrahimi   //  size<23:22> | Rm<20:16> | Rn<9:5> | rw<4> | Pd<3:0>
9790*f5c631daSSadaf Ebrahimi 
9791*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9792*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(rn.IsX() && rm.IsX());
9793*f5c631daSSadaf Ebrahimi 
9794*f5c631daSSadaf Ebrahimi   Emit(0x25203000 | SVESize(pd) | Pd(pd) | Rn(rn) | Rm(rm));
9795*f5c631daSSadaf Ebrahimi }
9796*f5c631daSSadaf Ebrahimi 
xar(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm,int shift)9797*f5c631daSSadaf Ebrahimi void Assembler::xar(const ZRegister& zd,
9798*f5c631daSSadaf Ebrahimi                     const ZRegister& zn,
9799*f5c631daSSadaf Ebrahimi                     const ZRegister& zm,
9800*f5c631daSSadaf Ebrahimi                     int shift) {
9801*f5c631daSSadaf Ebrahimi   // XAR <Zdn>.<T>, <Zdn>.<T>, <Zm>.<T>, #<const>
9802*f5c631daSSadaf Ebrahimi   //  0000 0100 ..1. .... 0011 01.. .... ....
9803*f5c631daSSadaf Ebrahimi   //  tszh<23:22> | tszl<20:19> | imm3<18:16> | Zm<9:5> | Zdn<4:0>
9804*f5c631daSSadaf Ebrahimi 
9805*f5c631daSSadaf Ebrahimi   USE(zn);
9806*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE2));
9807*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zd.Is(zn));
9808*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zd, zm));
9809*f5c631daSSadaf Ebrahimi 
9810*f5c631daSSadaf Ebrahimi   Instr encoded_imm =
9811*f5c631daSSadaf Ebrahimi       EncodeSVEShiftRightImmediate(shift, zd.GetLaneSizeInBits());
9812*f5c631daSSadaf Ebrahimi   SVEBitwiseShiftImmediate(zd, zm, encoded_imm, 0x04203400);
9813*f5c631daSSadaf Ebrahimi }
9814*f5c631daSSadaf Ebrahimi 
fmmla(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)9815*f5c631daSSadaf Ebrahimi void Assembler::fmmla(const ZRegister& zda,
9816*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
9817*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
9818*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
9819*f5c631daSSadaf Ebrahimi   VIXL_ASSERT((CPUHas(CPUFeatures::kSVEF32MM) && zda.IsLaneSizeS()) ||
9820*f5c631daSSadaf Ebrahimi               (CPUHas(CPUFeatures::kSVEF64MM) && zda.IsLaneSizeD()));
9821*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(AreSameLaneSize(zda, zn, zm));
9822*f5c631daSSadaf Ebrahimi 
9823*f5c631daSSadaf Ebrahimi   Emit(0x6420e400 | SVESize(zda) | Rd(zda) | Rn(zn) | Rm(zm));
9824*f5c631daSSadaf Ebrahimi }
9825*f5c631daSSadaf Ebrahimi 
smmla(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)9826*f5c631daSSadaf Ebrahimi void Assembler::smmla(const ZRegister& zda,
9827*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
9828*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
9829*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
9830*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVEI8MM));
9831*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.IsLaneSizeS());
9832*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.IsLaneSizeB() && zm.IsLaneSizeB());
9833*f5c631daSSadaf Ebrahimi 
9834*f5c631daSSadaf Ebrahimi   Emit(0x45009800 | Rd(zda) | Rn(zn) | Rm(zm));
9835*f5c631daSSadaf Ebrahimi }
9836*f5c631daSSadaf Ebrahimi 
usmmla(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)9837*f5c631daSSadaf Ebrahimi void Assembler::usmmla(const ZRegister& zda,
9838*f5c631daSSadaf Ebrahimi                        const ZRegister& zn,
9839*f5c631daSSadaf Ebrahimi                        const ZRegister& zm) {
9840*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
9841*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVEI8MM));
9842*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.IsLaneSizeS());
9843*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.IsLaneSizeB() && zm.IsLaneSizeB());
9844*f5c631daSSadaf Ebrahimi 
9845*f5c631daSSadaf Ebrahimi   Emit(0x45809800 | Rd(zda) | Rn(zn) | Rm(zm));
9846*f5c631daSSadaf Ebrahimi }
9847*f5c631daSSadaf Ebrahimi 
ummla(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)9848*f5c631daSSadaf Ebrahimi void Assembler::ummla(const ZRegister& zda,
9849*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
9850*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
9851*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
9852*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVEI8MM));
9853*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.IsLaneSizeS());
9854*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.IsLaneSizeB() && zm.IsLaneSizeB());
9855*f5c631daSSadaf Ebrahimi 
9856*f5c631daSSadaf Ebrahimi   Emit(0x45c09800 | Rd(zda) | Rn(zn) | Rm(zm));
9857*f5c631daSSadaf Ebrahimi }
9858*f5c631daSSadaf Ebrahimi 
usdot(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm)9859*f5c631daSSadaf Ebrahimi void Assembler::usdot(const ZRegister& zda,
9860*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
9861*f5c631daSSadaf Ebrahimi                       const ZRegister& zm) {
9862*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
9863*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVEI8MM));
9864*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.IsLaneSizeS());
9865*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.IsLaneSizeB() && zm.IsLaneSizeB());
9866*f5c631daSSadaf Ebrahimi 
9867*f5c631daSSadaf Ebrahimi   Emit(0x44807800 | Rd(zda) | Rn(zn) | Rm(zm));
9868*f5c631daSSadaf Ebrahimi }
9869*f5c631daSSadaf Ebrahimi 
usdot(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm,int index)9870*f5c631daSSadaf Ebrahimi void Assembler::usdot(const ZRegister& zda,
9871*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
9872*f5c631daSSadaf Ebrahimi                       const ZRegister& zm,
9873*f5c631daSSadaf Ebrahimi                       int index) {
9874*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
9875*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVEI8MM));
9876*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.IsLaneSizeS());
9877*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.IsLaneSizeB() && zm.IsLaneSizeB());
9878*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zm.GetCode() <= 7);
9879*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(IsUint2(index));
9880*f5c631daSSadaf Ebrahimi 
9881*f5c631daSSadaf Ebrahimi   Emit(0x44a01800 | Rx<18, 16>(zm) | (index << 19) | Rd(zda) | Rn(zn));
9882*f5c631daSSadaf Ebrahimi }
9883*f5c631daSSadaf Ebrahimi 
sudot(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm,int index)9884*f5c631daSSadaf Ebrahimi void Assembler::sudot(const ZRegister& zda,
9885*f5c631daSSadaf Ebrahimi                       const ZRegister& zn,
9886*f5c631daSSadaf Ebrahimi                       const ZRegister& zm,
9887*f5c631daSSadaf Ebrahimi                       int index) {
9888*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
9889*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(CPUHas(CPUFeatures::kSVEI8MM));
9890*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zda.IsLaneSizeS());
9891*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zn.IsLaneSizeB() && zm.IsLaneSizeB());
9892*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(zm.GetCode() <= 7);
9893*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(IsUint2(index));
9894*f5c631daSSadaf Ebrahimi 
9895*f5c631daSSadaf Ebrahimi   Emit(0x44a01c00 | Rx<18, 16>(zm) | (index << 19) | Rd(zda) | Rn(zn));
9896*f5c631daSSadaf Ebrahimi }
9897*f5c631daSSadaf Ebrahimi 
9898*f5c631daSSadaf Ebrahimi }  // namespace aarch64
9899*f5c631daSSadaf Ebrahimi }  // namespace vixl
9900