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