xref: /aosp_15_r20/external/swiftshader/third_party/subzero/src/IceAssemblerARM32.h (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1*03ce13f7SAndroid Build Coastguard Worker //===- subzero/src/IceAssemblerARM32.h - Assembler for ARM32 ----*- C++ -*-===//
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
4*03ce13f7SAndroid Build Coastguard Worker // for details. All rights reserved. Use of this source code is governed by a
5*03ce13f7SAndroid Build Coastguard Worker // BSD-style license that can be found in the LICENSE file.
6*03ce13f7SAndroid Build Coastguard Worker //
7*03ce13f7SAndroid Build Coastguard Worker // Modified by the Subzero authors.
8*03ce13f7SAndroid Build Coastguard Worker //
9*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
10*03ce13f7SAndroid Build Coastguard Worker //
11*03ce13f7SAndroid Build Coastguard Worker //                        The Subzero Code Generator
12*03ce13f7SAndroid Build Coastguard Worker //
13*03ce13f7SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
14*03ce13f7SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
15*03ce13f7SAndroid Build Coastguard Worker //
16*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
17*03ce13f7SAndroid Build Coastguard Worker ///
18*03ce13f7SAndroid Build Coastguard Worker /// \file
19*03ce13f7SAndroid Build Coastguard Worker /// \brief Declares the Assembler class for ARM32.
20*03ce13f7SAndroid Build Coastguard Worker ///
21*03ce13f7SAndroid Build Coastguard Worker /// Note: All references to ARM "section" documentation refers to the "ARM
22*03ce13f7SAndroid Build Coastguard Worker /// Architecture Reference Manual, ARMv7-A and ARMv7-R edition". See:
23*03ce13f7SAndroid Build Coastguard Worker /// http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0406c
24*03ce13f7SAndroid Build Coastguard Worker ///
25*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
26*03ce13f7SAndroid Build Coastguard Worker 
27*03ce13f7SAndroid Build Coastguard Worker #ifndef SUBZERO_SRC_ICEASSEMBLERARM32_H
28*03ce13f7SAndroid Build Coastguard Worker #define SUBZERO_SRC_ICEASSEMBLERARM32_H
29*03ce13f7SAndroid Build Coastguard Worker 
30*03ce13f7SAndroid Build Coastguard Worker #include "IceAssembler.h"
31*03ce13f7SAndroid Build Coastguard Worker #include "IceConditionCodesARM32.h"
32*03ce13f7SAndroid Build Coastguard Worker #include "IceDefs.h"
33*03ce13f7SAndroid Build Coastguard Worker #include "IceFixups.h"
34*03ce13f7SAndroid Build Coastguard Worker #include "IceInstARM32.h"
35*03ce13f7SAndroid Build Coastguard Worker #include "IceRegistersARM32.h"
36*03ce13f7SAndroid Build Coastguard Worker #include "IceTargetLowering.h"
37*03ce13f7SAndroid Build Coastguard Worker 
38*03ce13f7SAndroid Build Coastguard Worker namespace Ice {
39*03ce13f7SAndroid Build Coastguard Worker namespace ARM32 {
40*03ce13f7SAndroid Build Coastguard Worker 
41*03ce13f7SAndroid Build Coastguard Worker /// Handles encoding of bottom/top 16 bits of an address using movw/movt.
42*03ce13f7SAndroid Build Coastguard Worker class MoveRelocatableFixup final : public AssemblerFixup {
43*03ce13f7SAndroid Build Coastguard Worker   MoveRelocatableFixup &operator=(const MoveRelocatableFixup &) = delete;
44*03ce13f7SAndroid Build Coastguard Worker   MoveRelocatableFixup(const MoveRelocatableFixup &) = default;
45*03ce13f7SAndroid Build Coastguard Worker 
46*03ce13f7SAndroid Build Coastguard Worker public:
47*03ce13f7SAndroid Build Coastguard Worker   MoveRelocatableFixup() = default;
48*03ce13f7SAndroid Build Coastguard Worker   size_t emit(GlobalContext *Ctx, const Assembler &Asm) const final;
49*03ce13f7SAndroid Build Coastguard Worker   void emitOffset(Assembler *Asm) const;
50*03ce13f7SAndroid Build Coastguard Worker };
51*03ce13f7SAndroid Build Coastguard Worker 
52*03ce13f7SAndroid Build Coastguard Worker /// Handles encoding of branch and link to global location.
53*03ce13f7SAndroid Build Coastguard Worker class BlRelocatableFixup final : public AssemblerFixup {
54*03ce13f7SAndroid Build Coastguard Worker   BlRelocatableFixup(const BlRelocatableFixup &) = delete;
55*03ce13f7SAndroid Build Coastguard Worker   BlRelocatableFixup &operator=(const BlRelocatableFixup &) = delete;
56*03ce13f7SAndroid Build Coastguard Worker 
57*03ce13f7SAndroid Build Coastguard Worker public:
58*03ce13f7SAndroid Build Coastguard Worker   BlRelocatableFixup() = default;
59*03ce13f7SAndroid Build Coastguard Worker   size_t emit(GlobalContext *Ctx, const Assembler &Asm) const final;
60*03ce13f7SAndroid Build Coastguard Worker   void emitOffset(Assembler *Asm) const;
61*03ce13f7SAndroid Build Coastguard Worker };
62*03ce13f7SAndroid Build Coastguard Worker 
63*03ce13f7SAndroid Build Coastguard Worker class AssemblerARM32 : public Assembler {
64*03ce13f7SAndroid Build Coastguard Worker   AssemblerARM32(const AssemblerARM32 &) = delete;
65*03ce13f7SAndroid Build Coastguard Worker   AssemblerARM32 &operator=(const AssemblerARM32 &) = delete;
66*03ce13f7SAndroid Build Coastguard Worker 
67*03ce13f7SAndroid Build Coastguard Worker public:
68*03ce13f7SAndroid Build Coastguard Worker   // Rotation values.
69*03ce13f7SAndroid Build Coastguard Worker   enum RotationValue {
70*03ce13f7SAndroid Build Coastguard Worker     kRotateNone, // Omitted
71*03ce13f7SAndroid Build Coastguard Worker     kRotate8,    // ror #8
72*03ce13f7SAndroid Build Coastguard Worker     kRotate16,   // ror #16
73*03ce13f7SAndroid Build Coastguard Worker     kRotate24    // ror #24
74*03ce13f7SAndroid Build Coastguard Worker   };
75*03ce13f7SAndroid Build Coastguard Worker 
76*03ce13f7SAndroid Build Coastguard Worker   // Encoding of the number of D registers in a list of D registers.
77*03ce13f7SAndroid Build Coastguard Worker   enum DRegListSize {
78*03ce13f7SAndroid Build Coastguard Worker     DRegListSize1 = 7,  // 0b0111
79*03ce13f7SAndroid Build Coastguard Worker     DRegListSize2 = 10, // 0b1010
80*03ce13f7SAndroid Build Coastguard Worker     DRegListSIze3 = 6,  // 0b0110
81*03ce13f7SAndroid Build Coastguard Worker     DRegListSize4 = 2   // 0b0010
82*03ce13f7SAndroid Build Coastguard Worker   };
83*03ce13f7SAndroid Build Coastguard Worker 
84*03ce13f7SAndroid Build Coastguard Worker   class TargetInfo {
85*03ce13f7SAndroid Build Coastguard Worker     TargetInfo(const TargetInfo &) = delete;
86*03ce13f7SAndroid Build Coastguard Worker     TargetInfo &operator=(const TargetInfo &) = delete;
87*03ce13f7SAndroid Build Coastguard Worker 
88*03ce13f7SAndroid Build Coastguard Worker   public:
TargetInfo(bool HasFramePointer,RegNumT FrameOrStackReg)89*03ce13f7SAndroid Build Coastguard Worker     TargetInfo(bool HasFramePointer, RegNumT FrameOrStackReg)
90*03ce13f7SAndroid Build Coastguard Worker         : HasFramePointer(HasFramePointer), FrameOrStackReg(FrameOrStackReg) {}
TargetInfo(const TargetLowering * Target)91*03ce13f7SAndroid Build Coastguard Worker     explicit TargetInfo(const TargetLowering *Target)
92*03ce13f7SAndroid Build Coastguard Worker         : HasFramePointer(Target->hasFramePointer()),
93*03ce13f7SAndroid Build Coastguard Worker           FrameOrStackReg(Target->getFrameOrStackReg()) {}
94*03ce13f7SAndroid Build Coastguard Worker     const bool HasFramePointer;
95*03ce13f7SAndroid Build Coastguard Worker     const RegNumT FrameOrStackReg;
96*03ce13f7SAndroid Build Coastguard Worker   };
97*03ce13f7SAndroid Build Coastguard Worker 
AssemblerARM32()98*03ce13f7SAndroid Build Coastguard Worker   AssemblerARM32() : Assembler(Asm_ARM32) {}
~AssemblerARM32()99*03ce13f7SAndroid Build Coastguard Worker   ~AssemblerARM32() override {
100*03ce13f7SAndroid Build Coastguard Worker     if (BuildDefs::asserts()) {
101*03ce13f7SAndroid Build Coastguard Worker       for (const Label *Label : CfgNodeLabels) {
102*03ce13f7SAndroid Build Coastguard Worker         Label->finalCheck();
103*03ce13f7SAndroid Build Coastguard Worker       }
104*03ce13f7SAndroid Build Coastguard Worker       for (const Label *Label : LocalLabels) {
105*03ce13f7SAndroid Build Coastguard Worker         Label->finalCheck();
106*03ce13f7SAndroid Build Coastguard Worker       }
107*03ce13f7SAndroid Build Coastguard Worker     }
108*03ce13f7SAndroid Build Coastguard Worker   }
109*03ce13f7SAndroid Build Coastguard Worker 
110*03ce13f7SAndroid Build Coastguard Worker   MoveRelocatableFixup *createMoveFixup(bool IsMovW, const Constant *Value);
111*03ce13f7SAndroid Build Coastguard Worker 
112*03ce13f7SAndroid Build Coastguard Worker   BlRelocatableFixup *createBlFixup(const ConstantRelocatable *BlTarget);
113*03ce13f7SAndroid Build Coastguard Worker 
alignFunction()114*03ce13f7SAndroid Build Coastguard Worker   void alignFunction() override {
115*03ce13f7SAndroid Build Coastguard Worker     const SizeT Align = 1 << getBundleAlignLog2Bytes();
116*03ce13f7SAndroid Build Coastguard Worker     SizeT BytesNeeded = Utils::OffsetToAlignment(Buffer.getPosition(), Align);
117*03ce13f7SAndroid Build Coastguard Worker     constexpr SizeT InstSize = sizeof(IValueT);
118*03ce13f7SAndroid Build Coastguard Worker     assert(BytesNeeded % InstARM32::InstSize == 0);
119*03ce13f7SAndroid Build Coastguard Worker     while (BytesNeeded > 0) {
120*03ce13f7SAndroid Build Coastguard Worker       trap();
121*03ce13f7SAndroid Build Coastguard Worker       BytesNeeded -= InstSize;
122*03ce13f7SAndroid Build Coastguard Worker     }
123*03ce13f7SAndroid Build Coastguard Worker   }
124*03ce13f7SAndroid Build Coastguard Worker 
getBundleAlignLog2Bytes()125*03ce13f7SAndroid Build Coastguard Worker   SizeT getBundleAlignLog2Bytes() const override { return 4; }
126*03ce13f7SAndroid Build Coastguard Worker 
getAlignDirective()127*03ce13f7SAndroid Build Coastguard Worker   const char *getAlignDirective() const override { return ".p2alignl"; }
128*03ce13f7SAndroid Build Coastguard Worker 
129*03ce13f7SAndroid Build Coastguard Worker   llvm::ArrayRef<uint8_t> getNonExecBundlePadding() const override;
130*03ce13f7SAndroid Build Coastguard Worker 
131*03ce13f7SAndroid Build Coastguard Worker   void padWithNop(intptr_t Padding) override;
132*03ce13f7SAndroid Build Coastguard Worker 
getCfgNodeLabel(SizeT NodeNumber)133*03ce13f7SAndroid Build Coastguard Worker   Ice::Label *getCfgNodeLabel(SizeT NodeNumber) override {
134*03ce13f7SAndroid Build Coastguard Worker     assert(NodeNumber < CfgNodeLabels.size());
135*03ce13f7SAndroid Build Coastguard Worker     return CfgNodeLabels[NodeNumber];
136*03ce13f7SAndroid Build Coastguard Worker   }
137*03ce13f7SAndroid Build Coastguard Worker 
getOrCreateCfgNodeLabel(SizeT NodeNumber)138*03ce13f7SAndroid Build Coastguard Worker   Label *getOrCreateCfgNodeLabel(SizeT NodeNumber) {
139*03ce13f7SAndroid Build Coastguard Worker     return getOrCreateLabel(NodeNumber, CfgNodeLabels);
140*03ce13f7SAndroid Build Coastguard Worker   }
141*03ce13f7SAndroid Build Coastguard Worker 
getOrCreateLocalLabel(SizeT Number)142*03ce13f7SAndroid Build Coastguard Worker   Label *getOrCreateLocalLabel(SizeT Number) {
143*03ce13f7SAndroid Build Coastguard Worker     return getOrCreateLabel(Number, LocalLabels);
144*03ce13f7SAndroid Build Coastguard Worker   }
145*03ce13f7SAndroid Build Coastguard Worker 
bindLocalLabel(const InstARM32Label * InstL,SizeT Number)146*03ce13f7SAndroid Build Coastguard Worker   void bindLocalLabel(const InstARM32Label *InstL, SizeT Number) {
147*03ce13f7SAndroid Build Coastguard Worker     if (BuildDefs::dump() && !getFlags().getDisableHybridAssembly()) {
148*03ce13f7SAndroid Build Coastguard Worker       constexpr SizeT InstSize = 0;
149*03ce13f7SAndroid Build Coastguard Worker       emitTextInst(InstL->getLabelName() + ":", InstSize);
150*03ce13f7SAndroid Build Coastguard Worker     }
151*03ce13f7SAndroid Build Coastguard Worker     Label *L = getOrCreateLocalLabel(Number);
152*03ce13f7SAndroid Build Coastguard Worker     if (!getPreliminary())
153*03ce13f7SAndroid Build Coastguard Worker       this->bind(L);
154*03ce13f7SAndroid Build Coastguard Worker   }
155*03ce13f7SAndroid Build Coastguard Worker 
fixupIsPCRel(FixupKind Kind)156*03ce13f7SAndroid Build Coastguard Worker   bool fixupIsPCRel(FixupKind Kind) const override {
157*03ce13f7SAndroid Build Coastguard Worker     if (Kind == llvm::ELF::R_ARM_MOVW_PREL_NC)
158*03ce13f7SAndroid Build Coastguard Worker       return true;
159*03ce13f7SAndroid Build Coastguard Worker     if (Kind == llvm::ELF::R_ARM_MOVT_PREL)
160*03ce13f7SAndroid Build Coastguard Worker       return true;
161*03ce13f7SAndroid Build Coastguard Worker     return false;
162*03ce13f7SAndroid Build Coastguard Worker   }
163*03ce13f7SAndroid Build Coastguard Worker 
164*03ce13f7SAndroid Build Coastguard Worker   /// Accessors to keep track of the number of bytes generated inside
165*03ce13f7SAndroid Build Coastguard Worker   /// InstARM32::emit() methods, when run inside of
166*03ce13f7SAndroid Build Coastguard Worker   /// InstARM32::emitUsingTextFixup().
resetEmitTextSize()167*03ce13f7SAndroid Build Coastguard Worker   void resetEmitTextSize() { EmitTextSize = 0; }
incEmitTextSize(size_t Amount)168*03ce13f7SAndroid Build Coastguard Worker   void incEmitTextSize(size_t Amount) { EmitTextSize += Amount; }
decEmitTextSize(size_t Amount)169*03ce13f7SAndroid Build Coastguard Worker   void decEmitTextSize(size_t Amount) { EmitTextSize -= Amount; }
getEmitTextSize()170*03ce13f7SAndroid Build Coastguard Worker   size_t getEmitTextSize() const { return EmitTextSize; }
171*03ce13f7SAndroid Build Coastguard Worker 
172*03ce13f7SAndroid Build Coastguard Worker   void bind(Label *label);
173*03ce13f7SAndroid Build Coastguard Worker 
174*03ce13f7SAndroid Build Coastguard Worker   // List of instructions implemented by integrated assembler.
175*03ce13f7SAndroid Build Coastguard Worker 
176*03ce13f7SAndroid Build Coastguard Worker   void adc(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
177*03ce13f7SAndroid Build Coastguard Worker            bool SetFlags, CondARM32::Cond Cond);
178*03ce13f7SAndroid Build Coastguard Worker 
179*03ce13f7SAndroid Build Coastguard Worker   void add(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
180*03ce13f7SAndroid Build Coastguard Worker            bool SetFlags, CondARM32::Cond Cond);
181*03ce13f7SAndroid Build Coastguard Worker 
182*03ce13f7SAndroid Build Coastguard Worker   void and_(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
183*03ce13f7SAndroid Build Coastguard Worker             bool SetFlags, CondARM32::Cond Cond);
184*03ce13f7SAndroid Build Coastguard Worker 
185*03ce13f7SAndroid Build Coastguard Worker   void asr(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
186*03ce13f7SAndroid Build Coastguard Worker            bool SetFlags, CondARM32::Cond Cond);
187*03ce13f7SAndroid Build Coastguard Worker 
188*03ce13f7SAndroid Build Coastguard Worker   void b(Label *L, CondARM32::Cond Cond);
189*03ce13f7SAndroid Build Coastguard Worker 
190*03ce13f7SAndroid Build Coastguard Worker   void bkpt(uint16_t Imm16);
191*03ce13f7SAndroid Build Coastguard Worker 
192*03ce13f7SAndroid Build Coastguard Worker   void bic(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
193*03ce13f7SAndroid Build Coastguard Worker            bool SetFlags, CondARM32::Cond Cond);
194*03ce13f7SAndroid Build Coastguard Worker 
195*03ce13f7SAndroid Build Coastguard Worker   void bl(const ConstantRelocatable *Target);
196*03ce13f7SAndroid Build Coastguard Worker 
197*03ce13f7SAndroid Build Coastguard Worker   void blx(const Operand *Target);
198*03ce13f7SAndroid Build Coastguard Worker 
199*03ce13f7SAndroid Build Coastguard Worker   void bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond = CondARM32::AL);
200*03ce13f7SAndroid Build Coastguard Worker 
201*03ce13f7SAndroid Build Coastguard Worker   void clz(const Operand *OpRd, const Operand *OpSrc, CondARM32::Cond Cond);
202*03ce13f7SAndroid Build Coastguard Worker 
203*03ce13f7SAndroid Build Coastguard Worker   void cmn(const Operand *OpRn, const Operand *OpSrc1, CondARM32::Cond Cond);
204*03ce13f7SAndroid Build Coastguard Worker 
205*03ce13f7SAndroid Build Coastguard Worker   void cmp(const Operand *OpRn, const Operand *OpSrc1, CondARM32::Cond Cond);
206*03ce13f7SAndroid Build Coastguard Worker 
207*03ce13f7SAndroid Build Coastguard Worker   void dmb(IValueT Option); // Option is a 4-bit value.
208*03ce13f7SAndroid Build Coastguard Worker 
209*03ce13f7SAndroid Build Coastguard Worker   void eor(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
210*03ce13f7SAndroid Build Coastguard Worker            bool SetFlags, CondARM32::Cond Cond);
211*03ce13f7SAndroid Build Coastguard Worker 
212*03ce13f7SAndroid Build Coastguard Worker   void ldr(const Operand *OpRt, const Operand *OpAddress, CondARM32::Cond Cond,
213*03ce13f7SAndroid Build Coastguard Worker            const TargetInfo &TInfo);
214*03ce13f7SAndroid Build Coastguard Worker 
ldr(const Operand * OpRt,const Operand * OpAddress,CondARM32::Cond Cond,const TargetLowering * Lowering)215*03ce13f7SAndroid Build Coastguard Worker   void ldr(const Operand *OpRt, const Operand *OpAddress, CondARM32::Cond Cond,
216*03ce13f7SAndroid Build Coastguard Worker            const TargetLowering *Lowering) {
217*03ce13f7SAndroid Build Coastguard Worker     const TargetInfo TInfo(Lowering);
218*03ce13f7SAndroid Build Coastguard Worker     ldr(OpRt, OpAddress, Cond, TInfo);
219*03ce13f7SAndroid Build Coastguard Worker   }
220*03ce13f7SAndroid Build Coastguard Worker 
221*03ce13f7SAndroid Build Coastguard Worker   void ldrex(const Operand *OpRt, const Operand *OpAddress,
222*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond, const TargetInfo &TInfo);
223*03ce13f7SAndroid Build Coastguard Worker 
ldrex(const Operand * OpRt,const Operand * OpAddress,CondARM32::Cond Cond,const TargetLowering * Lowering)224*03ce13f7SAndroid Build Coastguard Worker   void ldrex(const Operand *OpRt, const Operand *OpAddress,
225*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond, const TargetLowering *Lowering) {
226*03ce13f7SAndroid Build Coastguard Worker     const TargetInfo TInfo(Lowering);
227*03ce13f7SAndroid Build Coastguard Worker     ldrex(OpRt, OpAddress, Cond, TInfo);
228*03ce13f7SAndroid Build Coastguard Worker   }
229*03ce13f7SAndroid Build Coastguard Worker 
230*03ce13f7SAndroid Build Coastguard Worker   void lsl(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
231*03ce13f7SAndroid Build Coastguard Worker            bool SetFlags, CondARM32::Cond Cond);
232*03ce13f7SAndroid Build Coastguard Worker 
233*03ce13f7SAndroid Build Coastguard Worker   void lsr(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
234*03ce13f7SAndroid Build Coastguard Worker            bool SetFlags, CondARM32::Cond Cond);
235*03ce13f7SAndroid Build Coastguard Worker 
236*03ce13f7SAndroid Build Coastguard Worker   void mov(const Operand *OpRd, const Operand *OpSrc, CondARM32::Cond Cond);
237*03ce13f7SAndroid Build Coastguard Worker 
238*03ce13f7SAndroid Build Coastguard Worker   void movw(const Operand *OpRd, const Operand *OpSrc, CondARM32::Cond Cond);
239*03ce13f7SAndroid Build Coastguard Worker 
240*03ce13f7SAndroid Build Coastguard Worker   void movt(const Operand *OpRd, const Operand *OpSrc, CondARM32::Cond Cond);
241*03ce13f7SAndroid Build Coastguard Worker 
242*03ce13f7SAndroid Build Coastguard Worker   void mla(const Operand *OpRd, const Operand *OpRn, const Operand *OpRm,
243*03ce13f7SAndroid Build Coastguard Worker            const Operand *OpRa, CondARM32::Cond Cond);
244*03ce13f7SAndroid Build Coastguard Worker 
245*03ce13f7SAndroid Build Coastguard Worker   void mls(const Operand *OpRd, const Operand *OpRn, const Operand *OpRm,
246*03ce13f7SAndroid Build Coastguard Worker            const Operand *OpRa, CondARM32::Cond Cond);
247*03ce13f7SAndroid Build Coastguard Worker 
248*03ce13f7SAndroid Build Coastguard Worker   void mul(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
249*03ce13f7SAndroid Build Coastguard Worker            bool SetFlags, CondARM32::Cond Cond);
250*03ce13f7SAndroid Build Coastguard Worker 
251*03ce13f7SAndroid Build Coastguard Worker   void mvn(const Operand *OpRd, const Operand *OpScc, CondARM32::Cond Cond);
252*03ce13f7SAndroid Build Coastguard Worker 
253*03ce13f7SAndroid Build Coastguard Worker   void nop();
254*03ce13f7SAndroid Build Coastguard Worker 
255*03ce13f7SAndroid Build Coastguard Worker   void orr(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
256*03ce13f7SAndroid Build Coastguard Worker            bool SetFlags, CondARM32::Cond Cond);
257*03ce13f7SAndroid Build Coastguard Worker 
258*03ce13f7SAndroid Build Coastguard Worker   void pop(const Variable *OpRt, CondARM32::Cond Cond);
259*03ce13f7SAndroid Build Coastguard Worker 
260*03ce13f7SAndroid Build Coastguard Worker   // Note: Registers is a bitset, where bit n corresponds to register Rn.
261*03ce13f7SAndroid Build Coastguard Worker   void popList(const IValueT Registers, CondARM32::Cond Cond);
262*03ce13f7SAndroid Build Coastguard Worker 
263*03ce13f7SAndroid Build Coastguard Worker   void push(const Operand *OpRt, CondARM32::Cond Cond);
264*03ce13f7SAndroid Build Coastguard Worker 
265*03ce13f7SAndroid Build Coastguard Worker   // Note: Registers is a bitset, where bit n corresponds to register Rn.
266*03ce13f7SAndroid Build Coastguard Worker   void pushList(const IValueT Registers, CondARM32::Cond Cond);
267*03ce13f7SAndroid Build Coastguard Worker 
268*03ce13f7SAndroid Build Coastguard Worker   void rbit(const Operand *OpRd, const Operand *OpRm, CondARM32::Cond Cond);
269*03ce13f7SAndroid Build Coastguard Worker 
270*03ce13f7SAndroid Build Coastguard Worker   void rev(const Operand *OpRd, const Operand *OpRm, CondARM32::Cond Cond);
271*03ce13f7SAndroid Build Coastguard Worker 
272*03ce13f7SAndroid Build Coastguard Worker   void rsb(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
273*03ce13f7SAndroid Build Coastguard Worker            bool SetFlags, CondARM32::Cond Cond);
274*03ce13f7SAndroid Build Coastguard Worker 
275*03ce13f7SAndroid Build Coastguard Worker   void rsc(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
276*03ce13f7SAndroid Build Coastguard Worker            bool SetFlags, CondARM32::Cond Cond);
277*03ce13f7SAndroid Build Coastguard Worker 
278*03ce13f7SAndroid Build Coastguard Worker   void sbc(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
279*03ce13f7SAndroid Build Coastguard Worker            bool SetFlags, CondARM32::Cond Cond);
280*03ce13f7SAndroid Build Coastguard Worker 
281*03ce13f7SAndroid Build Coastguard Worker   void sdiv(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
282*03ce13f7SAndroid Build Coastguard Worker             CondARM32::Cond Cond);
283*03ce13f7SAndroid Build Coastguard Worker 
284*03ce13f7SAndroid Build Coastguard Worker   void str(const Operand *OpRt, const Operand *OpAddress, CondARM32::Cond Cond,
285*03ce13f7SAndroid Build Coastguard Worker            const TargetInfo &TInfo);
286*03ce13f7SAndroid Build Coastguard Worker 
str(const Operand * OpRt,const Operand * OpAddress,CondARM32::Cond Cond,const TargetLowering * Lowering)287*03ce13f7SAndroid Build Coastguard Worker   void str(const Operand *OpRt, const Operand *OpAddress, CondARM32::Cond Cond,
288*03ce13f7SAndroid Build Coastguard Worker            const TargetLowering *Lowering) {
289*03ce13f7SAndroid Build Coastguard Worker     const TargetInfo TInfo(Lowering);
290*03ce13f7SAndroid Build Coastguard Worker     str(OpRt, OpAddress, Cond, TInfo);
291*03ce13f7SAndroid Build Coastguard Worker   }
292*03ce13f7SAndroid Build Coastguard Worker 
293*03ce13f7SAndroid Build Coastguard Worker   void strex(const Operand *OpRd, const Operand *OpRt, const Operand *OpAddress,
294*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond, const TargetInfo &TInfo);
295*03ce13f7SAndroid Build Coastguard Worker 
strex(const Operand * OpRd,const Operand * OpRt,const Operand * OpAddress,CondARM32::Cond Cond,const TargetLowering * Lowering)296*03ce13f7SAndroid Build Coastguard Worker   void strex(const Operand *OpRd, const Operand *OpRt, const Operand *OpAddress,
297*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond, const TargetLowering *Lowering) {
298*03ce13f7SAndroid Build Coastguard Worker     const TargetInfo TInfo(Lowering);
299*03ce13f7SAndroid Build Coastguard Worker     strex(OpRd, OpRt, OpAddress, Cond, TInfo);
300*03ce13f7SAndroid Build Coastguard Worker   }
301*03ce13f7SAndroid Build Coastguard Worker 
302*03ce13f7SAndroid Build Coastguard Worker   void sub(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
303*03ce13f7SAndroid Build Coastguard Worker            bool SetFlags, CondARM32::Cond Cond);
304*03ce13f7SAndroid Build Coastguard Worker 
305*03ce13f7SAndroid Build Coastguard Worker   // Implements sxtb/sxth depending on type of OpSrc0.
306*03ce13f7SAndroid Build Coastguard Worker   void sxt(const Operand *OpRd, const Operand *OpSrc0, CondARM32::Cond Cond);
307*03ce13f7SAndroid Build Coastguard Worker 
308*03ce13f7SAndroid Build Coastguard Worker   void trap();
309*03ce13f7SAndroid Build Coastguard Worker 
310*03ce13f7SAndroid Build Coastguard Worker   void tst(const Operand *OpRn, const Operand *OpSrc1, CondARM32::Cond Cond);
311*03ce13f7SAndroid Build Coastguard Worker 
312*03ce13f7SAndroid Build Coastguard Worker   void udiv(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
313*03ce13f7SAndroid Build Coastguard Worker             CondARM32::Cond Cond);
314*03ce13f7SAndroid Build Coastguard Worker 
315*03ce13f7SAndroid Build Coastguard Worker   void umull(const Operand *OpRdLo, const Operand *OpRdHi, const Operand *OpRn,
316*03ce13f7SAndroid Build Coastguard Worker              const Operand *OpRm, CondARM32::Cond Cond);
317*03ce13f7SAndroid Build Coastguard Worker 
318*03ce13f7SAndroid Build Coastguard Worker   // Implements uxtb/uxth depending on type of OpSrc0.
319*03ce13f7SAndroid Build Coastguard Worker   void uxt(const Operand *OpRd, const Operand *OpSrc0, CondARM32::Cond Cond);
320*03ce13f7SAndroid Build Coastguard Worker 
321*03ce13f7SAndroid Build Coastguard Worker   void vabss(const Operand *OpSd, const Operand *OpSm, CondARM32::Cond Cond);
322*03ce13f7SAndroid Build Coastguard Worker 
323*03ce13f7SAndroid Build Coastguard Worker   void vabsd(const Operand *OpDd, const Operand *OpDm, CondARM32::Cond Cond);
324*03ce13f7SAndroid Build Coastguard Worker 
325*03ce13f7SAndroid Build Coastguard Worker   void vabsq(const Operand *OpQd, const Operand *OpQm);
326*03ce13f7SAndroid Build Coastguard Worker 
327*03ce13f7SAndroid Build Coastguard Worker   void vaddd(const Operand *OpDd, const Operand *OpDn, const Operand *OpDm,
328*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond);
329*03ce13f7SAndroid Build Coastguard Worker 
330*03ce13f7SAndroid Build Coastguard Worker   void vadds(const Operand *OpSd, const Operand *OpSn, const Operand *OpSm,
331*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond);
332*03ce13f7SAndroid Build Coastguard Worker 
333*03ce13f7SAndroid Build Coastguard Worker   // Integer vector add.
334*03ce13f7SAndroid Build Coastguard Worker   void vaddqi(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
335*03ce13f7SAndroid Build Coastguard Worker               const Operand *OpQn);
336*03ce13f7SAndroid Build Coastguard Worker 
337*03ce13f7SAndroid Build Coastguard Worker   // Float vector add.
338*03ce13f7SAndroid Build Coastguard Worker   void vaddqf(const Operand *OpQd, const Operand *OpQm, const Operand *OpQn);
339*03ce13f7SAndroid Build Coastguard Worker 
340*03ce13f7SAndroid Build Coastguard Worker   void vandq(const Operand *OpQd, const Operand *OpQm, const Operand *OpQn);
341*03ce13f7SAndroid Build Coastguard Worker 
342*03ce13f7SAndroid Build Coastguard Worker   void vbslq(const Operand *OpQd, const Operand *OpQm, const Operand *OpQn);
343*03ce13f7SAndroid Build Coastguard Worker 
344*03ce13f7SAndroid Build Coastguard Worker   void vceqqi(const Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
345*03ce13f7SAndroid Build Coastguard Worker               const Operand *OpQn);
346*03ce13f7SAndroid Build Coastguard Worker 
347*03ce13f7SAndroid Build Coastguard Worker   void vceqqs(const Operand *OpQd, const Operand *OpQm, const Operand *OpQn);
348*03ce13f7SAndroid Build Coastguard Worker 
349*03ce13f7SAndroid Build Coastguard Worker   void vcgeqi(const Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
350*03ce13f7SAndroid Build Coastguard Worker               const Operand *OpQn);
351*03ce13f7SAndroid Build Coastguard Worker 
352*03ce13f7SAndroid Build Coastguard Worker   void vcugeqi(const Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
353*03ce13f7SAndroid Build Coastguard Worker                const Operand *OpQn);
354*03ce13f7SAndroid Build Coastguard Worker 
355*03ce13f7SAndroid Build Coastguard Worker   void vcgeqs(const Operand *OpQd, const Operand *OpQm, const Operand *OpQn);
356*03ce13f7SAndroid Build Coastguard Worker 
357*03ce13f7SAndroid Build Coastguard Worker   void vcgtqi(const Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
358*03ce13f7SAndroid Build Coastguard Worker               const Operand *OpQn);
359*03ce13f7SAndroid Build Coastguard Worker 
360*03ce13f7SAndroid Build Coastguard Worker   void vcugtqi(const Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
361*03ce13f7SAndroid Build Coastguard Worker                const Operand *OpQn);
362*03ce13f7SAndroid Build Coastguard Worker 
363*03ce13f7SAndroid Build Coastguard Worker   void vcgtqs(const Operand *OpQd, const Operand *OpQm, const Operand *OpQn);
364*03ce13f7SAndroid Build Coastguard Worker 
365*03ce13f7SAndroid Build Coastguard Worker   void vcmpd(const Operand *OpDd, const Operand *OpDm, CondARM32::Cond cond);
366*03ce13f7SAndroid Build Coastguard Worker 
367*03ce13f7SAndroid Build Coastguard Worker   // Second argument of compare is zero (+0.0).
368*03ce13f7SAndroid Build Coastguard Worker   void vcmpdz(const Operand *OpDd, CondARM32::Cond cond);
369*03ce13f7SAndroid Build Coastguard Worker 
370*03ce13f7SAndroid Build Coastguard Worker   void vcmps(const Operand *OpSd, const Operand *OpSm, CondARM32::Cond cond);
371*03ce13f7SAndroid Build Coastguard Worker 
372*03ce13f7SAndroid Build Coastguard Worker   // Second argument of compare is zero (+0.0).
373*03ce13f7SAndroid Build Coastguard Worker   void vcmpsz(const Operand *OpSd, CondARM32::Cond cond);
374*03ce13f7SAndroid Build Coastguard Worker 
375*03ce13f7SAndroid Build Coastguard Worker   void vcvtds(const Operand *OpDd, const Operand *OpSm, CondARM32::Cond Cond);
376*03ce13f7SAndroid Build Coastguard Worker 
377*03ce13f7SAndroid Build Coastguard Worker   // vcvt<c>.S32.F32
378*03ce13f7SAndroid Build Coastguard Worker   void vcvtis(const Operand *OpSd, const Operand *OpSm, CondARM32::Cond Cond);
379*03ce13f7SAndroid Build Coastguard Worker 
380*03ce13f7SAndroid Build Coastguard Worker   // vcvt<c>.S32.F64
381*03ce13f7SAndroid Build Coastguard Worker   void vcvtid(const Operand *OpSd, const Operand *OpDm, CondARM32::Cond Cond);
382*03ce13f7SAndroid Build Coastguard Worker 
383*03ce13f7SAndroid Build Coastguard Worker   // vcvt<c>.F64.S32
384*03ce13f7SAndroid Build Coastguard Worker   void vcvtdi(const Operand *OpDd, const Operand *OpSm, CondARM32::Cond Cond);
385*03ce13f7SAndroid Build Coastguard Worker 
386*03ce13f7SAndroid Build Coastguard Worker   // vcvt<c>.F64.U32
387*03ce13f7SAndroid Build Coastguard Worker   void vcvtdu(const Operand *OpDd, const Operand *OpSm, CondARM32::Cond Cond);
388*03ce13f7SAndroid Build Coastguard Worker 
389*03ce13f7SAndroid Build Coastguard Worker   void vcvtsd(const Operand *OpSd, const Operand *OpDm, CondARM32::Cond Cond);
390*03ce13f7SAndroid Build Coastguard Worker 
391*03ce13f7SAndroid Build Coastguard Worker   // vcvt<c>.F32.S32
392*03ce13f7SAndroid Build Coastguard Worker   void vcvtsi(const Operand *OpSd, const Operand *OpSm, CondARM32::Cond Cond);
393*03ce13f7SAndroid Build Coastguard Worker 
394*03ce13f7SAndroid Build Coastguard Worker   // vcvt<c>.F32.U32
395*03ce13f7SAndroid Build Coastguard Worker   void vcvtsu(const Operand *OpSd, const Operand *OpSm, CondARM32::Cond Cond);
396*03ce13f7SAndroid Build Coastguard Worker 
397*03ce13f7SAndroid Build Coastguard Worker   // vcvt<c>.U32.F64
398*03ce13f7SAndroid Build Coastguard Worker   void vcvtud(const Operand *OpSd, const Operand *OpDm, CondARM32::Cond Cond);
399*03ce13f7SAndroid Build Coastguard Worker 
400*03ce13f7SAndroid Build Coastguard Worker   // vcvt<c>.u32.f32
401*03ce13f7SAndroid Build Coastguard Worker   void vcvtus(const Operand *OpSd, const Operand *OpSm, CondARM32::Cond Cond);
402*03ce13f7SAndroid Build Coastguard Worker 
403*03ce13f7SAndroid Build Coastguard Worker   void vcvtqsi(const Operand *OpQd, const Operand *OpQm);
404*03ce13f7SAndroid Build Coastguard Worker 
405*03ce13f7SAndroid Build Coastguard Worker   void vcvtqsu(const Operand *OpQd, const Operand *OpQm);
406*03ce13f7SAndroid Build Coastguard Worker 
407*03ce13f7SAndroid Build Coastguard Worker   void vcvtqis(const Operand *OpQd, const Operand *OpQm);
408*03ce13f7SAndroid Build Coastguard Worker 
409*03ce13f7SAndroid Build Coastguard Worker   void vcvtqus(const Operand *OpQd, const Operand *OpQm);
410*03ce13f7SAndroid Build Coastguard Worker 
411*03ce13f7SAndroid Build Coastguard Worker   void vdivd(const Operand *OpDd, const Operand *OpDn, const Operand *OpDm,
412*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond);
413*03ce13f7SAndroid Build Coastguard Worker 
414*03ce13f7SAndroid Build Coastguard Worker   void vdivs(const Operand *OpSd, const Operand *OpSn, const Operand *OpSm,
415*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond);
416*03ce13f7SAndroid Build Coastguard Worker 
417*03ce13f7SAndroid Build Coastguard Worker   void veord(const Operand *OpDd, const Operand *OpDn, const Operand *OpDm);
418*03ce13f7SAndroid Build Coastguard Worker 
419*03ce13f7SAndroid Build Coastguard Worker   void veorq(const Operand *OpQd, const Operand *OpQn, const Operand *OpQm);
420*03ce13f7SAndroid Build Coastguard Worker 
421*03ce13f7SAndroid Build Coastguard Worker   void vldrd(const Operand *OpDd, const Operand *OpAddress,
422*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond, const TargetInfo &TInfo);
423*03ce13f7SAndroid Build Coastguard Worker 
vldrd(const Operand * OpDd,const Operand * OpAddress,CondARM32::Cond Cond,const TargetLowering * Lowering)424*03ce13f7SAndroid Build Coastguard Worker   void vldrd(const Operand *OpDd, const Operand *OpAddress,
425*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond, const TargetLowering *Lowering) {
426*03ce13f7SAndroid Build Coastguard Worker     const TargetInfo TInfo(Lowering);
427*03ce13f7SAndroid Build Coastguard Worker     vldrd(OpDd, OpAddress, Cond, TInfo);
428*03ce13f7SAndroid Build Coastguard Worker   }
429*03ce13f7SAndroid Build Coastguard Worker 
430*03ce13f7SAndroid Build Coastguard Worker   void vldrs(const Operand *OpSd, const Operand *OpAddress,
431*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond, const TargetInfo &TInfo);
432*03ce13f7SAndroid Build Coastguard Worker 
vldrs(const Operand * OpSd,const Operand * OpAddress,CondARM32::Cond Cond,const TargetLowering * Lowering)433*03ce13f7SAndroid Build Coastguard Worker   void vldrs(const Operand *OpSd, const Operand *OpAddress,
434*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond, const TargetLowering *Lowering) {
435*03ce13f7SAndroid Build Coastguard Worker     const TargetInfo TInfo(Lowering);
436*03ce13f7SAndroid Build Coastguard Worker     vldrs(OpSd, OpAddress, Cond, TInfo);
437*03ce13f7SAndroid Build Coastguard Worker   }
438*03ce13f7SAndroid Build Coastguard Worker 
439*03ce13f7SAndroid Build Coastguard Worker   void vldrq(const Operand *OpQd, const Operand *OpAddress,
440*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond, const TargetInfo &TInfo);
441*03ce13f7SAndroid Build Coastguard Worker 
vldrq(const Operand * OpQd,const Operand * OpAddress,CondARM32::Cond Cond,const TargetLowering * Lowering)442*03ce13f7SAndroid Build Coastguard Worker   void vldrq(const Operand *OpQd, const Operand *OpAddress,
443*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond, const TargetLowering *Lowering) {
444*03ce13f7SAndroid Build Coastguard Worker     const TargetInfo TInfo(Lowering);
445*03ce13f7SAndroid Build Coastguard Worker     vldrq(OpQd, OpAddress, Cond, TInfo);
446*03ce13f7SAndroid Build Coastguard Worker   }
447*03ce13f7SAndroid Build Coastguard Worker 
448*03ce13f7SAndroid Build Coastguard Worker   // ElmtSize = #bits in vector element.
449*03ce13f7SAndroid Build Coastguard Worker   void vld1qr(size_t ElmtSize, const Operand *OpQd, const Operand *OpRn,
450*03ce13f7SAndroid Build Coastguard Worker               const TargetInfo &TInfo);
451*03ce13f7SAndroid Build Coastguard Worker 
452*03ce13f7SAndroid Build Coastguard Worker   void vld1(size_t ElmtSize, const Operand *OpQd, const Operand *OpRn,
453*03ce13f7SAndroid Build Coastguard Worker             const TargetInfo &TInfo);
454*03ce13f7SAndroid Build Coastguard Worker 
vld1qr(size_t ElmtSize,const Operand * OpQd,const Operand * OpRn,const TargetLowering * Lowering)455*03ce13f7SAndroid Build Coastguard Worker   void vld1qr(size_t ElmtSize, const Operand *OpQd, const Operand *OpRn,
456*03ce13f7SAndroid Build Coastguard Worker               const TargetLowering *Lowering) {
457*03ce13f7SAndroid Build Coastguard Worker     const TargetInfo TInfo(Lowering);
458*03ce13f7SAndroid Build Coastguard Worker     vld1qr(ElmtSize, OpQd, OpRn, TInfo);
459*03ce13f7SAndroid Build Coastguard Worker   }
460*03ce13f7SAndroid Build Coastguard Worker 
vld1(size_t ElmtSize,const Operand * OpQd,const Operand * OpRn,const TargetLowering * Lowering)461*03ce13f7SAndroid Build Coastguard Worker   void vld1(size_t ElmtSize, const Operand *OpQd, const Operand *OpRn,
462*03ce13f7SAndroid Build Coastguard Worker             const TargetLowering *Lowering) {
463*03ce13f7SAndroid Build Coastguard Worker     const TargetInfo TInfo(Lowering);
464*03ce13f7SAndroid Build Coastguard Worker     vld1(ElmtSize, OpQd, OpRn, TInfo);
465*03ce13f7SAndroid Build Coastguard Worker   }
466*03ce13f7SAndroid Build Coastguard Worker 
467*03ce13f7SAndroid Build Coastguard Worker   // Qn[i] = Imm for all i in vector. Returns true iff Imm can be defined as an
468*03ce13f7SAndroid Build Coastguard Worker   // Imm8 using AdvSIMDExpandImm().
469*03ce13f7SAndroid Build Coastguard Worker   bool vmovqc(const Operand *OpQd, const ConstantInteger32 *Imm);
470*03ce13f7SAndroid Build Coastguard Worker 
471*03ce13f7SAndroid Build Coastguard Worker   // Dn = FpImm
472*03ce13f7SAndroid Build Coastguard Worker   void vmovd(const Operand *OpDn, const OperandARM32FlexFpImm *OpFpImm,
473*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond);
474*03ce13f7SAndroid Build Coastguard Worker 
475*03ce13f7SAndroid Build Coastguard Worker   // Dd = Dm
476*03ce13f7SAndroid Build Coastguard Worker   void vmovdd(const Operand *OpDd, const Variable *OpDm, CondARM32::Cond Cond);
477*03ce13f7SAndroid Build Coastguard Worker 
478*03ce13f7SAndroid Build Coastguard Worker   // Dm = Rt:Rt2
479*03ce13f7SAndroid Build Coastguard Worker   void vmovdrr(const Operand *OpDm, const Operand *OpRt, const Operand *OpRt2,
480*03ce13f7SAndroid Build Coastguard Worker                CondARM32::Cond Cond);
481*03ce13f7SAndroid Build Coastguard Worker 
482*03ce13f7SAndroid Build Coastguard Worker   // Qd[Index] = Rt
483*03ce13f7SAndroid Build Coastguard Worker   void vmovqir(const Operand *OpQd, uint32_t Index, const Operand *OpRt,
484*03ce13f7SAndroid Build Coastguard Worker                CondARM32::Cond Cond);
485*03ce13f7SAndroid Build Coastguard Worker 
486*03ce13f7SAndroid Build Coastguard Worker   // Qd[Index] = Sm
487*03ce13f7SAndroid Build Coastguard Worker   void vmovqis(const Operand *OpQd, uint32_t Indx, const Operand *OpSm,
488*03ce13f7SAndroid Build Coastguard Worker                CondARM32::Cond Cond);
489*03ce13f7SAndroid Build Coastguard Worker 
490*03ce13f7SAndroid Build Coastguard Worker   // Rt = Qm[Index]
491*03ce13f7SAndroid Build Coastguard Worker   void vmovrqi(const Operand *OpRt, const Operand *OpQd, uint32_t Index,
492*03ce13f7SAndroid Build Coastguard Worker                CondARM32::Cond Cond);
493*03ce13f7SAndroid Build Coastguard Worker 
494*03ce13f7SAndroid Build Coastguard Worker   // Rt:Rt2 = Dm
495*03ce13f7SAndroid Build Coastguard Worker   void vmovrrd(const Operand *OpRt, const Operand *OpRt2, const Operand *OpDm,
496*03ce13f7SAndroid Build Coastguard Worker                CondARM32::Cond Cond);
497*03ce13f7SAndroid Build Coastguard Worker 
498*03ce13f7SAndroid Build Coastguard Worker   // Rt = Sn
499*03ce13f7SAndroid Build Coastguard Worker   void vmovrs(const Operand *OpRt, const Operand *OpSn, CondARM32::Cond Cond);
500*03ce13f7SAndroid Build Coastguard Worker 
501*03ce13f7SAndroid Build Coastguard Worker   // Sn = FpImm
502*03ce13f7SAndroid Build Coastguard Worker   void vmovs(const Operand *OpSn, const OperandARM32FlexFpImm *OpFpImm,
503*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond);
504*03ce13f7SAndroid Build Coastguard Worker 
505*03ce13f7SAndroid Build Coastguard Worker   // Sd = Sm
506*03ce13f7SAndroid Build Coastguard Worker   void vmovss(const Operand *OpSd, const Variable *OpSm, CondARM32::Cond Cond);
507*03ce13f7SAndroid Build Coastguard Worker 
508*03ce13f7SAndroid Build Coastguard Worker   // Sd = Qm[Index]
509*03ce13f7SAndroid Build Coastguard Worker   void vmovsqi(const Operand *OpSd, const Operand *OpQm, uint32_t Index,
510*03ce13f7SAndroid Build Coastguard Worker                CondARM32::Cond Cond);
511*03ce13f7SAndroid Build Coastguard Worker 
512*03ce13f7SAndroid Build Coastguard Worker   // Sn = Rt
513*03ce13f7SAndroid Build Coastguard Worker   void vmovsr(const Operand *OpSn, const Operand *OpRt, CondARM32::Cond Cond);
514*03ce13f7SAndroid Build Coastguard Worker 
515*03ce13f7SAndroid Build Coastguard Worker   void vmlad(const Operand *OpDd, const Operand *OpDn, const Operand *OpDm,
516*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond);
517*03ce13f7SAndroid Build Coastguard Worker 
518*03ce13f7SAndroid Build Coastguard Worker   void vmlas(const Operand *OpSd, const Operand *OpSn, const Operand *OpSm,
519*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond);
520*03ce13f7SAndroid Build Coastguard Worker 
521*03ce13f7SAndroid Build Coastguard Worker   void vmlsd(const Operand *OpDd, const Operand *OpDn, const Operand *OpDm,
522*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond);
523*03ce13f7SAndroid Build Coastguard Worker 
524*03ce13f7SAndroid Build Coastguard Worker   void vmlss(const Operand *OpSd, const Operand *OpSn, const Operand *OpSm,
525*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond);
526*03ce13f7SAndroid Build Coastguard Worker 
527*03ce13f7SAndroid Build Coastguard Worker   // Uses APSR_nzcv as register
528*03ce13f7SAndroid Build Coastguard Worker   void vmrsAPSR_nzcv(CondARM32::Cond Cond);
529*03ce13f7SAndroid Build Coastguard Worker 
530*03ce13f7SAndroid Build Coastguard Worker   void vmuld(const Operand *OpDd, const Operand *OpDn, const Operand *OpDm,
531*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond);
532*03ce13f7SAndroid Build Coastguard Worker 
533*03ce13f7SAndroid Build Coastguard Worker   // Integer vector multiply.
534*03ce13f7SAndroid Build Coastguard Worker   void vmulqi(Type ElmtTy, const Operand *OpQd, const Operand *OpQn,
535*03ce13f7SAndroid Build Coastguard Worker               const Operand *OpQm);
536*03ce13f7SAndroid Build Coastguard Worker 
537*03ce13f7SAndroid Build Coastguard Worker   // Integer vector multiply high.
538*03ce13f7SAndroid Build Coastguard Worker   void vmulh(Type ElmtTy, const Operand *OpQd, const Operand *OpQn,
539*03ce13f7SAndroid Build Coastguard Worker              const Operand *OpQm, bool Unsigned);
540*03ce13f7SAndroid Build Coastguard Worker 
541*03ce13f7SAndroid Build Coastguard Worker   // Integer vector multiply add pairwise.
542*03ce13f7SAndroid Build Coastguard Worker   void vmlap(Type ElmtTy, const Operand *OpQd, const Operand *OpQn,
543*03ce13f7SAndroid Build Coastguard Worker              const Operand *OpQm);
544*03ce13f7SAndroid Build Coastguard Worker 
545*03ce13f7SAndroid Build Coastguard Worker   // Vector element replication.
546*03ce13f7SAndroid Build Coastguard Worker   void vdup(Type ElmtTy, const Operand *OpQd, const Operand *OpQn, IValueT Idx);
547*03ce13f7SAndroid Build Coastguard Worker 
548*03ce13f7SAndroid Build Coastguard Worker   // Vector interleave lower halves.
549*03ce13f7SAndroid Build Coastguard Worker   void vzip(Type ElmtTy, const Operand *OpQd, const Operand *OpQn,
550*03ce13f7SAndroid Build Coastguard Worker             const Operand *OpQm);
551*03ce13f7SAndroid Build Coastguard Worker 
552*03ce13f7SAndroid Build Coastguard Worker   // Float vector multiply.
553*03ce13f7SAndroid Build Coastguard Worker   void vmulqf(const Operand *OpQd, const Operand *OpQn, const Operand *OpQm);
554*03ce13f7SAndroid Build Coastguard Worker 
555*03ce13f7SAndroid Build Coastguard Worker   void vmuls(const Operand *OpSd, const Operand *OpSn, const Operand *OpSm,
556*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond);
557*03ce13f7SAndroid Build Coastguard Worker 
558*03ce13f7SAndroid Build Coastguard Worker   void vmvnq(const Operand *OpQd, const Operand *OpQm);
559*03ce13f7SAndroid Build Coastguard Worker 
560*03ce13f7SAndroid Build Coastguard Worker   void vmovlq(const Operand *OpQd, const Operand *OpQn, const Operand *OpQm);
561*03ce13f7SAndroid Build Coastguard Worker   void vmovhq(const Operand *OpQd, const Operand *OpQn, const Operand *OpQm);
562*03ce13f7SAndroid Build Coastguard Worker   void vmovhlq(const Operand *OpQd, const Operand *OpQn, const Operand *OpQm);
563*03ce13f7SAndroid Build Coastguard Worker   void vmovlhq(const Operand *OpQd, const Operand *OpQn, const Operand *OpQm);
564*03ce13f7SAndroid Build Coastguard Worker 
565*03ce13f7SAndroid Build Coastguard Worker   void vnegqs(const Operand *OpQd, const Operand *OpQm);
566*03ce13f7SAndroid Build Coastguard Worker 
567*03ce13f7SAndroid Build Coastguard Worker   void vnegqs(Type ElmtTy, const Operand *OpQd, const Operand *OpQm);
568*03ce13f7SAndroid Build Coastguard Worker 
569*03ce13f7SAndroid Build Coastguard Worker   void vorrq(const Operand *OpQd, const Operand *OpQm, const Operand *OpQn);
570*03ce13f7SAndroid Build Coastguard Worker 
571*03ce13f7SAndroid Build Coastguard Worker   void vpop(const Variable *OpBaseReg, SizeT NumConsecRegs,
572*03ce13f7SAndroid Build Coastguard Worker             CondARM32::Cond Cond);
573*03ce13f7SAndroid Build Coastguard Worker 
574*03ce13f7SAndroid Build Coastguard Worker   void vpush(const Variable *OpBaseReg, SizeT NumConsecRegs,
575*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond);
576*03ce13f7SAndroid Build Coastguard Worker 
577*03ce13f7SAndroid Build Coastguard Worker   void vshlqi(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
578*03ce13f7SAndroid Build Coastguard Worker               const Operand *OpQn);
579*03ce13f7SAndroid Build Coastguard Worker 
580*03ce13f7SAndroid Build Coastguard Worker   void vshlqu(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
581*03ce13f7SAndroid Build Coastguard Worker               const Operand *OpQn);
582*03ce13f7SAndroid Build Coastguard Worker 
583*03ce13f7SAndroid Build Coastguard Worker   void vshlqc(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
584*03ce13f7SAndroid Build Coastguard Worker               const ConstantInteger32 *OpQn);
585*03ce13f7SAndroid Build Coastguard Worker 
586*03ce13f7SAndroid Build Coastguard Worker   void vshrqc(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
587*03ce13f7SAndroid Build Coastguard Worker               const ConstantInteger32 *OpQn, InstARM32::FPSign Sign);
588*03ce13f7SAndroid Build Coastguard Worker 
589*03ce13f7SAndroid Build Coastguard Worker   void vsqrtd(const Operand *OpDd, const Operand *OpDm, CondARM32::Cond Cond);
590*03ce13f7SAndroid Build Coastguard Worker 
591*03ce13f7SAndroid Build Coastguard Worker   void vsqrts(const Operand *OpSd, const Operand *OpSm, CondARM32::Cond Cond);
592*03ce13f7SAndroid Build Coastguard Worker 
593*03ce13f7SAndroid Build Coastguard Worker   void vstrd(const Operand *OpDd, const Operand *OpAddress,
594*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond, const TargetInfo &TInfo);
595*03ce13f7SAndroid Build Coastguard Worker 
vstrd(const Operand * OpDd,const Operand * OpAddress,CondARM32::Cond Cond,const TargetLowering * Lowering)596*03ce13f7SAndroid Build Coastguard Worker   void vstrd(const Operand *OpDd, const Operand *OpAddress,
597*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond, const TargetLowering *Lowering) {
598*03ce13f7SAndroid Build Coastguard Worker     const TargetInfo TInfo(Lowering);
599*03ce13f7SAndroid Build Coastguard Worker     vstrd(OpDd, OpAddress, Cond, TInfo);
600*03ce13f7SAndroid Build Coastguard Worker   }
601*03ce13f7SAndroid Build Coastguard Worker 
602*03ce13f7SAndroid Build Coastguard Worker   void vstrs(const Operand *OpSd, const Operand *OpAddress,
603*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond, const TargetInfo &TInfo);
604*03ce13f7SAndroid Build Coastguard Worker 
vstrs(const Operand * OpSd,const Operand * OpAddress,CondARM32::Cond Cond,const TargetLowering * Lowering)605*03ce13f7SAndroid Build Coastguard Worker   void vstrs(const Operand *OpSd, const Operand *OpAddress,
606*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond, const TargetLowering *Lowering) {
607*03ce13f7SAndroid Build Coastguard Worker     const TargetInfo TInfo(Lowering);
608*03ce13f7SAndroid Build Coastguard Worker     vstrs(OpSd, OpAddress, Cond, TInfo);
609*03ce13f7SAndroid Build Coastguard Worker   }
610*03ce13f7SAndroid Build Coastguard Worker 
611*03ce13f7SAndroid Build Coastguard Worker   void vstrq(const Operand *OpQd, const Operand *OpAddress,
612*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond, const TargetInfo &TInfo);
613*03ce13f7SAndroid Build Coastguard Worker 
vstrq(const Operand * OpQd,const Operand * OpAddress,CondARM32::Cond Cond,const TargetLowering * Lowering)614*03ce13f7SAndroid Build Coastguard Worker   void vstrq(const Operand *OpQd, const Operand *OpAddress,
615*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond, const TargetLowering *Lowering) {
616*03ce13f7SAndroid Build Coastguard Worker     const TargetInfo TInfo(Lowering);
617*03ce13f7SAndroid Build Coastguard Worker     vstrq(OpQd, OpAddress, Cond, TInfo);
618*03ce13f7SAndroid Build Coastguard Worker   }
619*03ce13f7SAndroid Build Coastguard Worker 
620*03ce13f7SAndroid Build Coastguard Worker   // ElmtSize = #bits in vector element.
621*03ce13f7SAndroid Build Coastguard Worker   void vst1qr(size_t ElmtSize, const Operand *OpQd, const Operand *OpAddress,
622*03ce13f7SAndroid Build Coastguard Worker               const TargetInfo &TInfo);
623*03ce13f7SAndroid Build Coastguard Worker 
vst1qr(size_t ElmtSize,const Operand * OpQd,const Operand * OpRn,const TargetLowering * Lowering)624*03ce13f7SAndroid Build Coastguard Worker   void vst1qr(size_t ElmtSize, const Operand *OpQd, const Operand *OpRn,
625*03ce13f7SAndroid Build Coastguard Worker               const TargetLowering *Lowering) {
626*03ce13f7SAndroid Build Coastguard Worker     const TargetInfo TInfo(Lowering);
627*03ce13f7SAndroid Build Coastguard Worker     vst1qr(ElmtSize, OpQd, OpRn, TInfo);
628*03ce13f7SAndroid Build Coastguard Worker   }
629*03ce13f7SAndroid Build Coastguard Worker 
630*03ce13f7SAndroid Build Coastguard Worker   void vst1(size_t ElmtSize, const Operand *OpQd, const Operand *OpAddress,
631*03ce13f7SAndroid Build Coastguard Worker             const TargetInfo &TInfo);
632*03ce13f7SAndroid Build Coastguard Worker 
vst1(size_t ElmtSize,const Operand * OpQd,const Operand * OpRn,const TargetLowering * Lowering)633*03ce13f7SAndroid Build Coastguard Worker   void vst1(size_t ElmtSize, const Operand *OpQd, const Operand *OpRn,
634*03ce13f7SAndroid Build Coastguard Worker             const TargetLowering *Lowering) {
635*03ce13f7SAndroid Build Coastguard Worker     const TargetInfo TInfo(Lowering);
636*03ce13f7SAndroid Build Coastguard Worker     vst1(ElmtSize, OpQd, OpRn, TInfo);
637*03ce13f7SAndroid Build Coastguard Worker   }
638*03ce13f7SAndroid Build Coastguard Worker 
639*03ce13f7SAndroid Build Coastguard Worker   void vsubd(const Operand *OpDd, const Operand *OpDn, const Operand *OpDm,
640*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond);
641*03ce13f7SAndroid Build Coastguard Worker 
642*03ce13f7SAndroid Build Coastguard Worker   // Integer vector subtract.
643*03ce13f7SAndroid Build Coastguard Worker   void vsubqi(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
644*03ce13f7SAndroid Build Coastguard Worker               const Operand *OpQn);
645*03ce13f7SAndroid Build Coastguard Worker 
646*03ce13f7SAndroid Build Coastguard Worker   // Integer vector saturating subtract.
647*03ce13f7SAndroid Build Coastguard Worker   void vqsubqi(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
648*03ce13f7SAndroid Build Coastguard Worker                const Operand *OpQn);
649*03ce13f7SAndroid Build Coastguard Worker   void vqsubqu(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
650*03ce13f7SAndroid Build Coastguard Worker                const Operand *OpQn);
651*03ce13f7SAndroid Build Coastguard Worker 
652*03ce13f7SAndroid Build Coastguard Worker   // Integer vector saturating add.
653*03ce13f7SAndroid Build Coastguard Worker   void vqaddqi(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
654*03ce13f7SAndroid Build Coastguard Worker                const Operand *OpQn);
655*03ce13f7SAndroid Build Coastguard Worker   void vqaddqu(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
656*03ce13f7SAndroid Build Coastguard Worker                const Operand *OpQn);
657*03ce13f7SAndroid Build Coastguard Worker 
658*03ce13f7SAndroid Build Coastguard Worker   // Integer vector packing with optional saturation.
659*03ce13f7SAndroid Build Coastguard Worker   void vqmovn2(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
660*03ce13f7SAndroid Build Coastguard Worker                const Operand *OpQn, bool Unsigned, bool Saturating);
661*03ce13f7SAndroid Build Coastguard Worker 
662*03ce13f7SAndroid Build Coastguard Worker   // Float vector subtract
663*03ce13f7SAndroid Build Coastguard Worker   void vsubqf(const Operand *OpQd, const Operand *OpQm, const Operand *OpQn);
664*03ce13f7SAndroid Build Coastguard Worker 
665*03ce13f7SAndroid Build Coastguard Worker   void vsubs(const Operand *OpSd, const Operand *OpSn, const Operand *OpSm,
666*03ce13f7SAndroid Build Coastguard Worker              CondARM32::Cond Cond);
667*03ce13f7SAndroid Build Coastguard Worker 
classof(const Assembler * Asm)668*03ce13f7SAndroid Build Coastguard Worker   static bool classof(const Assembler *Asm) {
669*03ce13f7SAndroid Build Coastguard Worker     return Asm->getKind() == Asm_ARM32;
670*03ce13f7SAndroid Build Coastguard Worker   }
671*03ce13f7SAndroid Build Coastguard Worker 
672*03ce13f7SAndroid Build Coastguard Worker   void emitTextInst(const std::string &Text, SizeT InstSize);
673*03ce13f7SAndroid Build Coastguard Worker 
674*03ce13f7SAndroid Build Coastguard Worker private:
675*03ce13f7SAndroid Build Coastguard Worker   ENABLE_MAKE_UNIQUE;
676*03ce13f7SAndroid Build Coastguard Worker 
677*03ce13f7SAndroid Build Coastguard Worker   // A vector of pool-allocated x86 labels for CFG nodes.
678*03ce13f7SAndroid Build Coastguard Worker   using LabelVector = std::vector<Label *>;
679*03ce13f7SAndroid Build Coastguard Worker   LabelVector CfgNodeLabels;
680*03ce13f7SAndroid Build Coastguard Worker   // A vector of pool-allocated x86 labels for Local labels.
681*03ce13f7SAndroid Build Coastguard Worker   LabelVector LocalLabels;
682*03ce13f7SAndroid Build Coastguard Worker   // Number of bytes emitted by InstARM32::emit() methods, when run inside
683*03ce13f7SAndroid Build Coastguard Worker   // InstARM32::emitUsingTextFixup().
684*03ce13f7SAndroid Build Coastguard Worker   size_t EmitTextSize = 0;
685*03ce13f7SAndroid Build Coastguard Worker 
686*03ce13f7SAndroid Build Coastguard Worker   // Load/store multiple addressing mode.
687*03ce13f7SAndroid Build Coastguard Worker   enum BlockAddressMode {
688*03ce13f7SAndroid Build Coastguard Worker     // bit encoding P U W
689*03ce13f7SAndroid Build Coastguard Worker     DA = (0 | 0 | 0) << 21,   // decrement after
690*03ce13f7SAndroid Build Coastguard Worker     IA = (0 | 4 | 0) << 21,   // increment after
691*03ce13f7SAndroid Build Coastguard Worker     DB = (8 | 0 | 0) << 21,   // decrement before
692*03ce13f7SAndroid Build Coastguard Worker     IB = (8 | 4 | 0) << 21,   // increment before
693*03ce13f7SAndroid Build Coastguard Worker     DA_W = (0 | 0 | 1) << 21, // decrement after with writeback to base
694*03ce13f7SAndroid Build Coastguard Worker     IA_W = (0 | 4 | 1) << 21, // increment after with writeback to base
695*03ce13f7SAndroid Build Coastguard Worker     DB_W = (8 | 0 | 1) << 21, // decrement before with writeback to base
696*03ce13f7SAndroid Build Coastguard Worker     IB_W = (8 | 4 | 1) << 21  // increment before with writeback to base
697*03ce13f7SAndroid Build Coastguard Worker   };
698*03ce13f7SAndroid Build Coastguard Worker 
699*03ce13f7SAndroid Build Coastguard Worker   Label *getOrCreateLabel(SizeT Number, LabelVector &Labels);
700*03ce13f7SAndroid Build Coastguard Worker 
701*03ce13f7SAndroid Build Coastguard Worker   void bindCfgNodeLabel(const CfgNode *Node) override;
702*03ce13f7SAndroid Build Coastguard Worker 
703*03ce13f7SAndroid Build Coastguard Worker   // SIMD encoding for the vector ElmtTy.
704*03ce13f7SAndroid Build Coastguard Worker   static IValueT encodeElmtType(Type ElmtTy);
705*03ce13f7SAndroid Build Coastguard Worker 
emitInst(IValueT Value)706*03ce13f7SAndroid Build Coastguard Worker   void emitInst(IValueT Value) {
707*03ce13f7SAndroid Build Coastguard Worker     AssemblerBuffer::EnsureCapacity _(&Buffer);
708*03ce13f7SAndroid Build Coastguard Worker     Buffer.emit<IValueT>(Value);
709*03ce13f7SAndroid Build Coastguard Worker   }
710*03ce13f7SAndroid Build Coastguard Worker 
711*03ce13f7SAndroid Build Coastguard Worker   // List of possible checks to apply when calling emitType01() (below).
712*03ce13f7SAndroid Build Coastguard Worker   enum EmitChecks { NoChecks, RdIsPcAndSetFlags };
713*03ce13f7SAndroid Build Coastguard Worker 
714*03ce13f7SAndroid Build Coastguard Worker   // Pattern cccctttoooosnnnnddddiiiiiiiiiiii where cccc=Cond, ttt=InstType,
715*03ce13f7SAndroid Build Coastguard Worker   // s=SetFlags, oooo=Opcode, nnnn=Rn, dddd=Rd, iiiiiiiiiiii=imm12 (See ARM
716*03ce13f7SAndroid Build Coastguard Worker   // section A5.2.3).
717*03ce13f7SAndroid Build Coastguard Worker   void emitType01(CondARM32::Cond Cond, IValueT InstType, IValueT Opcode,
718*03ce13f7SAndroid Build Coastguard Worker                   bool SetFlags, IValueT Rn, IValueT Rd, IValueT imm12,
719*03ce13f7SAndroid Build Coastguard Worker                   EmitChecks RuleChecks, const char *InstName);
720*03ce13f7SAndroid Build Coastguard Worker 
721*03ce13f7SAndroid Build Coastguard Worker   // Converts appropriate representation on a data operation, and then calls
722*03ce13f7SAndroid Build Coastguard Worker   // emitType01 above.
723*03ce13f7SAndroid Build Coastguard Worker   void emitType01(CondARM32::Cond Cond, IValueT Opcode, const Operand *OpRd,
724*03ce13f7SAndroid Build Coastguard Worker                   const Operand *OpRn, const Operand *OpSrc1, bool SetFlags,
725*03ce13f7SAndroid Build Coastguard Worker                   EmitChecks RuleChecks, const char *InstName);
726*03ce13f7SAndroid Build Coastguard Worker 
727*03ce13f7SAndroid Build Coastguard Worker   // Same as above, but the value for Rd and Rn have already been converted
728*03ce13f7SAndroid Build Coastguard Worker   // into instruction values.
729*03ce13f7SAndroid Build Coastguard Worker   void emitType01(CondARM32::Cond Cond, IValueT Opcode, IValueT OpRd,
730*03ce13f7SAndroid Build Coastguard Worker                   IValueT OpRn, const Operand *OpSrc1, bool SetFlags,
731*03ce13f7SAndroid Build Coastguard Worker                   EmitChecks RuleChecks, const char *InstName);
732*03ce13f7SAndroid Build Coastguard Worker 
733*03ce13f7SAndroid Build Coastguard Worker   void emitType05(CondARM32::Cond Cond, int32_t Offset, bool Link);
734*03ce13f7SAndroid Build Coastguard Worker 
735*03ce13f7SAndroid Build Coastguard Worker   // Emit ccccoooaabalnnnnttttaaaaaaaaaaaa where cccc=Cond,
736*03ce13f7SAndroid Build Coastguard Worker   // ooo=InstType, l=isLoad, b=isByte, and
737*03ce13f7SAndroid Build Coastguard Worker   // aaa0a0aaaa0000aaaaaaaaaaaa=Address. Note that Address is assumed to be
738*03ce13f7SAndroid Build Coastguard Worker   // defined by decodeAddress() in IceAssemblerARM32.cpp.
739*03ce13f7SAndroid Build Coastguard Worker   void emitMemOp(CondARM32::Cond Cond, IValueT InstType, bool IsLoad,
740*03ce13f7SAndroid Build Coastguard Worker                  bool IsByte, IValueT Rt, IValueT Address);
741*03ce13f7SAndroid Build Coastguard Worker 
742*03ce13f7SAndroid Build Coastguard Worker   // Emit ccccxxxxxxxxxxxxddddxxxxxxxxmmmm where cccc=Cond,
743*03ce13f7SAndroid Build Coastguard Worker   // xxxxxxxxxxxx0000xxxxxxxx0000=Opcode, dddd=Rd, and mmmm=Rm.
744*03ce13f7SAndroid Build Coastguard Worker   void emitRdRm(CondARM32::Cond Cond, IValueT Opcode, const Operand *OpRd,
745*03ce13f7SAndroid Build Coastguard Worker                 const Operand *OpRm, const char *InstName);
746*03ce13f7SAndroid Build Coastguard Worker 
747*03ce13f7SAndroid Build Coastguard Worker   // Emit ldr/ldrb/str/strb instruction with given address.
748*03ce13f7SAndroid Build Coastguard Worker   void emitMemOp(CondARM32::Cond Cond, bool IsLoad, bool IsByte, IValueT Rt,
749*03ce13f7SAndroid Build Coastguard Worker                  const Operand *OpAddress, const TargetInfo &TInfo,
750*03ce13f7SAndroid Build Coastguard Worker                  const char *InstName);
751*03ce13f7SAndroid Build Coastguard Worker 
752*03ce13f7SAndroid Build Coastguard Worker   // Emit ldrh/ldrd/strh/strd instruction with given address using encoding 3.
753*03ce13f7SAndroid Build Coastguard Worker   void emitMemOpEnc3(CondARM32::Cond Cond, IValueT Opcode, IValueT Rt,
754*03ce13f7SAndroid Build Coastguard Worker                      const Operand *OpAddress, const TargetInfo &TInfo,
755*03ce13f7SAndroid Build Coastguard Worker                      const char *InstName);
756*03ce13f7SAndroid Build Coastguard Worker 
757*03ce13f7SAndroid Build Coastguard Worker   // Emit cccc00011xxlnnnndddd11111001tttt where cccc=Cond, xx encodes type
758*03ce13f7SAndroid Build Coastguard Worker   // size, l=IsLoad, nnnn=Rn (as defined by OpAddress), and tttt=Rt.
759*03ce13f7SAndroid Build Coastguard Worker   void emitMemExOp(CondARM32::Cond, Type Ty, bool IsLoad, const Operand *OpRd,
760*03ce13f7SAndroid Build Coastguard Worker                    IValueT Rt, const Operand *OpAddress,
761*03ce13f7SAndroid Build Coastguard Worker                    const TargetInfo &TInfo, const char *InstName);
762*03ce13f7SAndroid Build Coastguard Worker 
763*03ce13f7SAndroid Build Coastguard Worker   // Pattern cccc100aaaalnnnnrrrrrrrrrrrrrrrr where cccc=Cond,
764*03ce13f7SAndroid Build Coastguard Worker   // aaaa<<21=AddressMode, l=IsLoad, nnnn=BaseReg, and
765*03ce13f7SAndroid Build Coastguard Worker   // rrrrrrrrrrrrrrrr is bitset of Registers.
766*03ce13f7SAndroid Build Coastguard Worker   void emitMultiMemOp(CondARM32::Cond Cond, BlockAddressMode AddressMode,
767*03ce13f7SAndroid Build Coastguard Worker                       bool IsLoad, IValueT BaseReg, IValueT Registers);
768*03ce13f7SAndroid Build Coastguard Worker 
769*03ce13f7SAndroid Build Coastguard Worker   // Pattern ccccxxxxxDxxxxxxddddxxxxiiiiiiii where cccc=Cond, ddddD=BaseReg,
770*03ce13f7SAndroid Build Coastguard Worker   // iiiiiiii=NumConsecRegs, and xxxxx0xxxxxx0000xxxx00000000=Opcode.
771*03ce13f7SAndroid Build Coastguard Worker   void emitVStackOp(CondARM32::Cond Cond, IValueT Opcode,
772*03ce13f7SAndroid Build Coastguard Worker                     const Variable *OpBaseReg, SizeT NumConsecRegs);
773*03ce13f7SAndroid Build Coastguard Worker 
774*03ce13f7SAndroid Build Coastguard Worker   // Pattern cccc111xxDxxxxxxdddd101xxxMxmmmm where cccc=Cond, ddddD=Sd,
775*03ce13f7SAndroid Build Coastguard Worker   // Mmmmm=Dm, and xx0xxxxxxdddd000xxx0x0000=Opcode.
776*03ce13f7SAndroid Build Coastguard Worker   void emitVFPsd(CondARM32::Cond Cond, IValueT Opcode, IValueT Sd, IValueT Dm);
777*03ce13f7SAndroid Build Coastguard Worker 
778*03ce13f7SAndroid Build Coastguard Worker   // Pattern cccc111xxDxxxxxxdddd101xxxMxmmmm where cccc=Cond, Ddddd=Dd,
779*03ce13f7SAndroid Build Coastguard Worker   // mmmmM=Sm, and xx0xxxxxxdddd000xxx0x0000=Opcode.
780*03ce13f7SAndroid Build Coastguard Worker   void emitVFPds(CondARM32::Cond Cond, IValueT Opcode, IValueT Dd, IValueT Sm);
781*03ce13f7SAndroid Build Coastguard Worker 
782*03ce13f7SAndroid Build Coastguard Worker   // Pattern 111100000D00nnnnddddttttssaammmm | Opcode where Ddddd=Dd, nnnn=Rn,
783*03ce13f7SAndroid Build Coastguard Worker   // mmmmm=Rm, tttt=NumDRegs, ElmtSize in {8, 16, 32, 64) and defines ss, and
784*03ce13f7SAndroid Build Coastguard Worker   // aa=Align.
785*03ce13f7SAndroid Build Coastguard Worker   void emitVMem1Op(IValueT Opcode, IValueT Dd, IValueT Rn, IValueT Rm,
786*03ce13f7SAndroid Build Coastguard Worker                    DRegListSize NumDRegs, size_t ElmtSize, IValueT Align,
787*03ce13f7SAndroid Build Coastguard Worker                    const char *InstName);
788*03ce13f7SAndroid Build Coastguard Worker 
789*03ce13f7SAndroid Build Coastguard Worker   // Pattern 111100000D00nnnnddddss00aaaammmm | Opcode where Ddddd=Dd, nnnn=Rn,
790*03ce13f7SAndroid Build Coastguard Worker   // mmmmm=Rm, ElmtSize in {8, 16, 32) and defines ss, and aa=Align.
791*03ce13f7SAndroid Build Coastguard Worker   void emitVMem1Op(IValueT Opcode, IValueT Dd, IValueT Rn, IValueT Rm,
792*03ce13f7SAndroid Build Coastguard Worker                    size_t ElmtSize, IValueT Align, const char *InstName);
793*03ce13f7SAndroid Build Coastguard Worker 
794*03ce13f7SAndroid Build Coastguard Worker   // Pattern cccc011100x1dddd1111mmmm0001nnn where cccc=Cond,
795*03ce13f7SAndroid Build Coastguard Worker   // x=Opcode, dddd=Rd, nnnn=Rn, mmmm=Rm.
796*03ce13f7SAndroid Build Coastguard Worker   void emitDivOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd, IValueT Rn,
797*03ce13f7SAndroid Build Coastguard Worker                  IValueT Rm);
798*03ce13f7SAndroid Build Coastguard Worker 
799*03ce13f7SAndroid Build Coastguard Worker   // cccc1110iiiennnntttt1011Njj10000 where cccc=Cond, tttt=Rt, Ndddd=2*Qn=Dn,
800*03ce13f7SAndroid Build Coastguard Worker   // iii=Opcode1, jj=Opcode2, Opcode1Opcode2 encodes Index and the
801*03ce13f7SAndroid Build Coastguard Worker   // corresponding element size of the vector element, and e=IsExtract.
802*03ce13f7SAndroid Build Coastguard Worker   void emitInsertExtractInt(CondARM32::Cond Cond, const Operand *OpQn,
803*03ce13f7SAndroid Build Coastguard Worker                             uint32_t Index, const Operand *OpRt, bool IsExtract,
804*03ce13f7SAndroid Build Coastguard Worker                             const char *InstName);
805*03ce13f7SAndroid Build Coastguard Worker 
806*03ce13f7SAndroid Build Coastguard Worker   // cccc11101D110000dddd101001M0mmmm where cccc=Cond, ddddD=Sd, and mmmmM=Sm.
807*03ce13f7SAndroid Build Coastguard Worker   // Assigns Sd the value of Sm.
808*03ce13f7SAndroid Build Coastguard Worker   void emitMoveSS(CondARM32::Cond Cond, IValueT Sd, IValueT Sm);
809*03ce13f7SAndroid Build Coastguard Worker 
810*03ce13f7SAndroid Build Coastguard Worker   // Pattern ccccxxxxxxxfnnnnddddssss1001mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
811*03ce13f7SAndroid Build Coastguard Worker   // mmmm=Rm, ssss=Rs, f=SetFlags and xxxxxxx=Opcode.
812*03ce13f7SAndroid Build Coastguard Worker   void emitMulOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd, IValueT Rn,
813*03ce13f7SAndroid Build Coastguard Worker                  IValueT Rm, IValueT Rs, bool SetFlags);
814*03ce13f7SAndroid Build Coastguard Worker 
815*03ce13f7SAndroid Build Coastguard Worker   // Pattern cccc0001101s0000ddddxxxxxtt0mmmm where cccc=Cond, s=SetFlags,
816*03ce13f7SAndroid Build Coastguard Worker   // dddd=Rd, mmmm=Rm, tt=Shift, and xxxxx is defined by OpSrc1. OpSrc1 defines
817*03ce13f7SAndroid Build Coastguard Worker   // either xxxxx=Imm5, or xxxxx=ssss0 where ssss=Rs.
818*03ce13f7SAndroid Build Coastguard Worker   void emitShift(const CondARM32::Cond Cond,
819*03ce13f7SAndroid Build Coastguard Worker                  const OperandARM32::ShiftKind Shift, const Operand *OpRd,
820*03ce13f7SAndroid Build Coastguard Worker                  const Operand *OpRm, const Operand *OpSrc1,
821*03ce13f7SAndroid Build Coastguard Worker                  const bool SetFlags, const char *InstName);
822*03ce13f7SAndroid Build Coastguard Worker 
823*03ce13f7SAndroid Build Coastguard Worker   // Implements various forms of signed/unsigned extend value, using pattern
824*03ce13f7SAndroid Build Coastguard Worker   // ccccxxxxxxxxnnnnddddrr000111mmmm where cccc=Cond, xxxxxxxx<<20=Opcode,
825*03ce13f7SAndroid Build Coastguard Worker   // nnnn=Rn, dddd=Rd, rr=Rotation, and mmmm=Rm.
826*03ce13f7SAndroid Build Coastguard Worker   void emitSignExtend(CondARM32::Cond, IValueT Opcode, const Operand *OpRd,
827*03ce13f7SAndroid Build Coastguard Worker                       const Operand *OpSrc0, const char *InstName);
828*03ce13f7SAndroid Build Coastguard Worker 
829*03ce13f7SAndroid Build Coastguard Worker   // Implements various forms of vector (SIMD) operations.  Implements pattern
830*03ce13f7SAndroid Build Coastguard Worker   // 111100100D00nnnndddn00F0NQM0mmmm where Dddd=Dd, Nnnn=Dn, Mmmm=Dm,
831*03ce13f7SAndroid Build Coastguard Worker   // Q=UseQRegs, F=IsFloatTy, and Opcode is unioned into the pattern.
832*03ce13f7SAndroid Build Coastguard Worker   void emitSIMDBase(IValueT Opcode, IValueT Dd, IValueT Dn, IValueT Dm,
833*03ce13f7SAndroid Build Coastguard Worker                     bool UseQRegs, bool IsFloatTy);
834*03ce13f7SAndroid Build Coastguard Worker 
835*03ce13f7SAndroid Build Coastguard Worker   // Same as emitSIMDBase above, except ElmtShift=20 and ElmtSize is computed
836*03ce13f7SAndroid Build Coastguard Worker   // from ElmtTy.
837*03ce13f7SAndroid Build Coastguard Worker   void emitSIMD(IValueT Opcode, Type ElmtTy, IValueT Dd, IValueT Dn, IValueT Dm,
838*03ce13f7SAndroid Build Coastguard Worker                 bool UseQRegs);
839*03ce13f7SAndroid Build Coastguard Worker 
840*03ce13f7SAndroid Build Coastguard Worker   // Implements various integer forms of vector (SIMD) operations using Q
841*03ce13f7SAndroid Build Coastguard Worker   // registers. Implements pattern 111100100D00nnn0ddd000F0N1M0mmm0 where
842*03ce13f7SAndroid Build Coastguard Worker   // Dddd=Qd, Nnnn=Qn, Mmmm=Qm, F=IsFloatTy, and Opcode is unioned into the
843*03ce13f7SAndroid Build Coastguard Worker   // pattern.
844*03ce13f7SAndroid Build Coastguard Worker   void emitSIMDqqqBase(IValueT Opcode, const Operand *OpQd, const Operand *OpQn,
845*03ce13f7SAndroid Build Coastguard Worker                        const Operand *OpQm, bool IsFloatTy,
846*03ce13f7SAndroid Build Coastguard Worker                        const char *OpcodeName);
847*03ce13f7SAndroid Build Coastguard Worker 
848*03ce13f7SAndroid Build Coastguard Worker   // Same as emitSIMD above, except ElmtShift=20 and ElmtSize is computed from
849*03ce13f7SAndroid Build Coastguard Worker   // ElmtTy.
850*03ce13f7SAndroid Build Coastguard Worker   void emitSIMDqqq(IValueT Opcode, Type ElmtTy, const Operand *OpQd,
851*03ce13f7SAndroid Build Coastguard Worker                    const Operand *OpQn, const Operand *OpQm,
852*03ce13f7SAndroid Build Coastguard Worker                    const char *OpcodeName);
853*03ce13f7SAndroid Build Coastguard Worker 
854*03ce13f7SAndroid Build Coastguard Worker   // Implements various forms of vector (SIMD) shifts using Q registers.
855*03ce13f7SAndroid Build Coastguard Worker   // Implements pattern 111100101Diiiiiidddd010101M1mmmm where Dddd=Qd, Mmmm=Qm,
856*03ce13f7SAndroid Build Coastguard Worker   // iiiiii=Imm6, and Opcode is unioned into the pattern.
857*03ce13f7SAndroid Build Coastguard Worker   void emitSIMDShiftqqc(IValueT Opcode, const Operand *OpQd,
858*03ce13f7SAndroid Build Coastguard Worker                         const Operand *OpQm, const IValueT Imm6,
859*03ce13f7SAndroid Build Coastguard Worker                         const char *OpcodeName);
860*03ce13f7SAndroid Build Coastguard Worker 
861*03ce13f7SAndroid Build Coastguard Worker   // Implements various forms of vector (SIMD) casts between (signed and
862*03ce13f7SAndroid Build Coastguard Worker   // unsigned) integer and floating point types (f32). Implements pattern
863*03ce13f7SAndroid Build Coastguard Worker   // 111100111D11ss11dddd011ooQM0mmmm where Dddd=Qd, Mmmm=Qm, 10=ss, op=00, 1=Q,
864*03ce13f7SAndroid Build Coastguard Worker   // and Opcode is unioned into the pattern.
865*03ce13f7SAndroid Build Coastguard Worker   void emitSIMDCvtqq(IValueT Opcode, const Operand *OpQd, const Operand *OpQm,
866*03ce13f7SAndroid Build Coastguard Worker                      const char *CvtName);
867*03ce13f7SAndroid Build Coastguard Worker 
868*03ce13f7SAndroid Build Coastguard Worker   // Pattern cccctttxxxxnnnn0000iiiiiiiiiiii where cccc=Cond, nnnn=Rn,
869*03ce13f7SAndroid Build Coastguard Worker   // ttt=Instruction type (derived from OpSrc1), iiiiiiiiiiii is derived from
870*03ce13f7SAndroid Build Coastguard Worker   // OpSrc1, and xxxx=Opcode.
871*03ce13f7SAndroid Build Coastguard Worker   void emitCompareOp(CondARM32::Cond Cond, IValueT Opcode, const Operand *OpRn,
872*03ce13f7SAndroid Build Coastguard Worker                      const Operand *OpSrc1, const char *CmpName);
873*03ce13f7SAndroid Build Coastguard Worker 
874*03ce13f7SAndroid Build Coastguard Worker   void emitBranch(Label *L, CondARM32::Cond, bool Link);
875*03ce13f7SAndroid Build Coastguard Worker 
876*03ce13f7SAndroid Build Coastguard Worker   // Returns the offset encoded in the branch instruction Inst.
877*03ce13f7SAndroid Build Coastguard Worker   static IOffsetT decodeBranchOffset(IValueT Inst);
878*03ce13f7SAndroid Build Coastguard Worker 
879*03ce13f7SAndroid Build Coastguard Worker   // Implements movw/movt, generating pattern ccccxxxxxxxsiiiiddddiiiiiiiiiiii
880*03ce13f7SAndroid Build Coastguard Worker   // where cccc=Cond, xxxxxxx<<21=Opcode, dddd=Rd, s=SetFlags, and
881*03ce13f7SAndroid Build Coastguard Worker   // iiiiiiiiiiiiiiii=Imm16.
882*03ce13f7SAndroid Build Coastguard Worker   void emitMovwt(CondARM32::Cond Cond, bool IsMovw, const Operand *OpRd,
883*03ce13f7SAndroid Build Coastguard Worker                  const Operand *OpSrc, const char *MovName);
884*03ce13f7SAndroid Build Coastguard Worker 
885*03ce13f7SAndroid Build Coastguard Worker   // Emit VFP instruction with 3 D registers.
886*03ce13f7SAndroid Build Coastguard Worker   void emitVFPddd(CondARM32::Cond Cond, IValueT Opcode, const Operand *OpDd,
887*03ce13f7SAndroid Build Coastguard Worker                   const Operand *OpDn, const Operand *OpDm,
888*03ce13f7SAndroid Build Coastguard Worker                   const char *InstName);
889*03ce13f7SAndroid Build Coastguard Worker 
890*03ce13f7SAndroid Build Coastguard Worker   void emitVFPddd(CondARM32::Cond Cond, IValueT Opcode, IValueT Dd, IValueT Dn,
891*03ce13f7SAndroid Build Coastguard Worker                   IValueT Dm);
892*03ce13f7SAndroid Build Coastguard Worker 
893*03ce13f7SAndroid Build Coastguard Worker   // Emit VFP instruction with 3 S registers.
894*03ce13f7SAndroid Build Coastguard Worker   void emitVFPsss(CondARM32::Cond Cond, IValueT Opcode, IValueT Sd, IValueT Sn,
895*03ce13f7SAndroid Build Coastguard Worker                   IValueT Sm);
896*03ce13f7SAndroid Build Coastguard Worker 
897*03ce13f7SAndroid Build Coastguard Worker   void emitVFPsss(CondARM32::Cond Cond, IValueT Opcode, const Operand *OpSd,
898*03ce13f7SAndroid Build Coastguard Worker                   const Operand *OpSn, const Operand *OpSm,
899*03ce13f7SAndroid Build Coastguard Worker                   const char *InstName);
900*03ce13f7SAndroid Build Coastguard Worker };
901*03ce13f7SAndroid Build Coastguard Worker 
902*03ce13f7SAndroid Build Coastguard Worker } // end of namespace ARM32
903*03ce13f7SAndroid Build Coastguard Worker } // end of namespace Ice
904*03ce13f7SAndroid Build Coastguard Worker 
905*03ce13f7SAndroid Build Coastguard Worker #endif // SUBZERO_SRC_ICEASSEMBLERARM32_H
906