xref: /aosp_15_r20/external/swiftshader/third_party/subzero/src/IceTargetLoweringX8664.h (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1*03ce13f7SAndroid Build Coastguard Worker //===- subzero/src/IceTargetLoweringX8664.h - lowering for x86-64 -*- C++ -*-=//
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker //                        The Subzero Code Generator
4*03ce13f7SAndroid Build Coastguard Worker //
5*03ce13f7SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*03ce13f7SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*03ce13f7SAndroid Build Coastguard Worker //
8*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*03ce13f7SAndroid Build Coastguard Worker ///
10*03ce13f7SAndroid Build Coastguard Worker /// \file
11*03ce13f7SAndroid Build Coastguard Worker /// \brief Declares the TargetLoweringX8664 class, which implements the
12*03ce13f7SAndroid Build Coastguard Worker /// TargetLowering interface for the X86 64-bit architecture.
13*03ce13f7SAndroid Build Coastguard Worker ///
14*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
15*03ce13f7SAndroid Build Coastguard Worker 
16*03ce13f7SAndroid Build Coastguard Worker #ifndef SUBZERO_SRC_ICETARGETLOWERINGX8664_H
17*03ce13f7SAndroid Build Coastguard Worker #define SUBZERO_SRC_ICETARGETLOWERINGX8664_H
18*03ce13f7SAndroid Build Coastguard Worker 
19*03ce13f7SAndroid Build Coastguard Worker #include "IceAssemblerX8664.h"
20*03ce13f7SAndroid Build Coastguard Worker #include "IceCfg.h"
21*03ce13f7SAndroid Build Coastguard Worker #include "IceDefs.h"
22*03ce13f7SAndroid Build Coastguard Worker #include "IceGlobalContext.h"
23*03ce13f7SAndroid Build Coastguard Worker #include "IceInst.h"
24*03ce13f7SAndroid Build Coastguard Worker #include "IceInstX8664.h"
25*03ce13f7SAndroid Build Coastguard Worker #include "IceSwitchLowering.h"
26*03ce13f7SAndroid Build Coastguard Worker #include "IceTargetLoweringX86.h"
27*03ce13f7SAndroid Build Coastguard Worker #include "IceTargetLoweringX86RegClass.h"
28*03ce13f7SAndroid Build Coastguard Worker #include "IceUtils.h"
29*03ce13f7SAndroid Build Coastguard Worker 
30*03ce13f7SAndroid Build Coastguard Worker #include <array>
31*03ce13f7SAndroid Build Coastguard Worker #include <type_traits>
32*03ce13f7SAndroid Build Coastguard Worker #include <utility>
33*03ce13f7SAndroid Build Coastguard Worker 
34*03ce13f7SAndroid Build Coastguard Worker namespace Ice {
35*03ce13f7SAndroid Build Coastguard Worker namespace X8664 {
36*03ce13f7SAndroid Build Coastguard Worker 
37*03ce13f7SAndroid Build Coastguard Worker using namespace ::Ice::X86;
38*03ce13f7SAndroid Build Coastguard Worker 
39*03ce13f7SAndroid Build Coastguard Worker constexpr Type WordType = IceType_i64;
40*03ce13f7SAndroid Build Coastguard Worker 
41*03ce13f7SAndroid Build Coastguard Worker class BoolFoldingEntry {
42*03ce13f7SAndroid Build Coastguard Worker   BoolFoldingEntry(const BoolFoldingEntry &) = delete;
43*03ce13f7SAndroid Build Coastguard Worker 
44*03ce13f7SAndroid Build Coastguard Worker public:
45*03ce13f7SAndroid Build Coastguard Worker   BoolFoldingEntry() = default;
46*03ce13f7SAndroid Build Coastguard Worker   explicit BoolFoldingEntry(Inst *I);
47*03ce13f7SAndroid Build Coastguard Worker   BoolFoldingEntry &operator=(const BoolFoldingEntry &) = default;
48*03ce13f7SAndroid Build Coastguard Worker   /// Instr is the instruction producing the i1-type variable of interest.
49*03ce13f7SAndroid Build Coastguard Worker   Inst *Instr = nullptr;
50*03ce13f7SAndroid Build Coastguard Worker   /// IsComplex is the cached result of BoolFolding::hasComplexLowering(Instr).
51*03ce13f7SAndroid Build Coastguard Worker   bool IsComplex = false;
52*03ce13f7SAndroid Build Coastguard Worker   /// IsLiveOut is initialized conservatively to true, and is set to false when
53*03ce13f7SAndroid Build Coastguard Worker   /// we encounter an instruction that ends Var's live range. We disable the
54*03ce13f7SAndroid Build Coastguard Worker   /// folding optimization when Var is live beyond this basic block. Note that
55*03ce13f7SAndroid Build Coastguard Worker   /// if liveness analysis is not performed (e.g. in Om1 mode), IsLiveOut will
56*03ce13f7SAndroid Build Coastguard Worker   /// always be true and the folding optimization will never be performed.
57*03ce13f7SAndroid Build Coastguard Worker   bool IsLiveOut = true;
58*03ce13f7SAndroid Build Coastguard Worker   // NumUses counts the number of times Var is used as a source operand in the
59*03ce13f7SAndroid Build Coastguard Worker   // basic block. If IsComplex is true and there is more than one use of Var,
60*03ce13f7SAndroid Build Coastguard Worker   // then the folding optimization is disabled for Var.
61*03ce13f7SAndroid Build Coastguard Worker   uint32_t NumUses = 0;
62*03ce13f7SAndroid Build Coastguard Worker };
63*03ce13f7SAndroid Build Coastguard Worker 
64*03ce13f7SAndroid Build Coastguard Worker class BoolFolding {
65*03ce13f7SAndroid Build Coastguard Worker public:
66*03ce13f7SAndroid Build Coastguard Worker   enum BoolFoldingProducerKind {
67*03ce13f7SAndroid Build Coastguard Worker     PK_None,
68*03ce13f7SAndroid Build Coastguard Worker     // TODO(jpp): PK_Icmp32 is no longer meaningful. Rename to PK_IcmpNative.
69*03ce13f7SAndroid Build Coastguard Worker     PK_Icmp32,
70*03ce13f7SAndroid Build Coastguard Worker     PK_Icmp64,
71*03ce13f7SAndroid Build Coastguard Worker     PK_Fcmp,
72*03ce13f7SAndroid Build Coastguard Worker     PK_Trunc,
73*03ce13f7SAndroid Build Coastguard Worker     PK_Arith // A flag-setting arithmetic instruction.
74*03ce13f7SAndroid Build Coastguard Worker   };
75*03ce13f7SAndroid Build Coastguard Worker 
76*03ce13f7SAndroid Build Coastguard Worker   /// Currently the actual enum values are not used (other than CK_None), but we
77*03ce13f7SAndroid Build Coastguard Worker   /// go ahead and produce them anyway for symmetry with the
78*03ce13f7SAndroid Build Coastguard Worker   /// BoolFoldingProducerKind.
79*03ce13f7SAndroid Build Coastguard Worker   enum BoolFoldingConsumerKind { CK_None, CK_Br, CK_Select, CK_Sext, CK_Zext };
80*03ce13f7SAndroid Build Coastguard Worker 
81*03ce13f7SAndroid Build Coastguard Worker private:
82*03ce13f7SAndroid Build Coastguard Worker   BoolFolding(const BoolFolding &) = delete;
83*03ce13f7SAndroid Build Coastguard Worker   BoolFolding &operator=(const BoolFolding &) = delete;
84*03ce13f7SAndroid Build Coastguard Worker 
85*03ce13f7SAndroid Build Coastguard Worker public:
86*03ce13f7SAndroid Build Coastguard Worker   BoolFolding() = default;
87*03ce13f7SAndroid Build Coastguard Worker   static BoolFoldingProducerKind getProducerKind(const Inst *Instr);
88*03ce13f7SAndroid Build Coastguard Worker   static BoolFoldingConsumerKind getConsumerKind(const Inst *Instr);
89*03ce13f7SAndroid Build Coastguard Worker   static bool hasComplexLowering(const Inst *Instr);
90*03ce13f7SAndroid Build Coastguard Worker   static bool isValidFolding(BoolFoldingProducerKind ProducerKind,
91*03ce13f7SAndroid Build Coastguard Worker                              BoolFoldingConsumerKind ConsumerKind);
92*03ce13f7SAndroid Build Coastguard Worker   void init(CfgNode *Node);
93*03ce13f7SAndroid Build Coastguard Worker   const Inst *getProducerFor(const Operand *Opnd) const;
94*03ce13f7SAndroid Build Coastguard Worker   void dump(const Cfg *Func) const;
95*03ce13f7SAndroid Build Coastguard Worker 
96*03ce13f7SAndroid Build Coastguard Worker private:
97*03ce13f7SAndroid Build Coastguard Worker   /// Returns true if Producers contains a valid entry for the given VarNum.
containsValid(SizeT VarNum)98*03ce13f7SAndroid Build Coastguard Worker   bool containsValid(SizeT VarNum) const {
99*03ce13f7SAndroid Build Coastguard Worker     auto Element = Producers.find(VarNum);
100*03ce13f7SAndroid Build Coastguard Worker     return Element != Producers.end() && Element->second.Instr != nullptr;
101*03ce13f7SAndroid Build Coastguard Worker   }
setInvalid(SizeT VarNum)102*03ce13f7SAndroid Build Coastguard Worker   void setInvalid(SizeT VarNum) { Producers[VarNum].Instr = nullptr; }
103*03ce13f7SAndroid Build Coastguard Worker   void invalidateProducersOnStore(const Inst *Instr);
104*03ce13f7SAndroid Build Coastguard Worker   /// Producers maps Variable::Number to a BoolFoldingEntry.
105*03ce13f7SAndroid Build Coastguard Worker   CfgUnorderedMap<SizeT, BoolFoldingEntry> Producers;
106*03ce13f7SAndroid Build Coastguard Worker };
107*03ce13f7SAndroid Build Coastguard Worker 
108*03ce13f7SAndroid Build Coastguard Worker class TargetX8664 : public TargetX86 {
109*03ce13f7SAndroid Build Coastguard Worker   TargetX8664() = delete;
110*03ce13f7SAndroid Build Coastguard Worker   TargetX8664(const TargetX8664 &) = delete;
111*03ce13f7SAndroid Build Coastguard Worker   TargetX8664 &operator=(const TargetX8664 &) = delete;
112*03ce13f7SAndroid Build Coastguard Worker 
113*03ce13f7SAndroid Build Coastguard Worker   friend class BoolFolding;
114*03ce13f7SAndroid Build Coastguard Worker 
115*03ce13f7SAndroid Build Coastguard Worker public:
116*03ce13f7SAndroid Build Coastguard Worker   using BrCond = CondX86::BrCond;
117*03ce13f7SAndroid Build Coastguard Worker   using CmppsCond = CondX86::CmppsCond;
118*03ce13f7SAndroid Build Coastguard Worker 
119*03ce13f7SAndroid Build Coastguard Worker   using SegmentRegisters = X86OperandMem::SegmentRegisters;
120*03ce13f7SAndroid Build Coastguard Worker 
121*03ce13f7SAndroid Build Coastguard Worker   using InstX86Br = Insts::Br;
122*03ce13f7SAndroid Build Coastguard Worker   using InstX86FakeRMW = Insts::FakeRMW;
123*03ce13f7SAndroid Build Coastguard Worker   using InstX86Label = Insts::Label;
124*03ce13f7SAndroid Build Coastguard Worker 
125*03ce13f7SAndroid Build Coastguard Worker   ~TargetX8664() override = default;
126*03ce13f7SAndroid Build Coastguard Worker 
127*03ce13f7SAndroid Build Coastguard Worker   static void staticInit(GlobalContext *Ctx);
128*03ce13f7SAndroid Build Coastguard Worker   static bool shouldBePooled(const Constant *C);
129*03ce13f7SAndroid Build Coastguard Worker   static ::Ice::Type getPointerType();
130*03ce13f7SAndroid Build Coastguard Worker 
131*03ce13f7SAndroid Build Coastguard Worker   void translateOm1() override;
132*03ce13f7SAndroid Build Coastguard Worker   void translateO2() override;
133*03ce13f7SAndroid Build Coastguard Worker   void doLoadOpt();
134*03ce13f7SAndroid Build Coastguard Worker   bool doBranchOpt(Inst *I, const CfgNode *NextNode) override;
135*03ce13f7SAndroid Build Coastguard Worker 
getNumRegisters()136*03ce13f7SAndroid Build Coastguard Worker   SizeT getNumRegisters() const override { return RegisterSet::Reg_NUM; }
137*03ce13f7SAndroid Build Coastguard Worker 
createLoweredMove(Variable * Dest,Variable * SrcVar)138*03ce13f7SAndroid Build Coastguard Worker   Inst *createLoweredMove(Variable *Dest, Variable *SrcVar) override {
139*03ce13f7SAndroid Build Coastguard Worker     if (isVectorType(Dest->getType())) {
140*03ce13f7SAndroid Build Coastguard Worker       return Insts::Movp::create(Func, Dest, SrcVar);
141*03ce13f7SAndroid Build Coastguard Worker     }
142*03ce13f7SAndroid Build Coastguard Worker     return Insts::Mov::create(Func, Dest, SrcVar);
143*03ce13f7SAndroid Build Coastguard Worker     (void)Dest;
144*03ce13f7SAndroid Build Coastguard Worker     (void)SrcVar;
145*03ce13f7SAndroid Build Coastguard Worker     return nullptr;
146*03ce13f7SAndroid Build Coastguard Worker   }
147*03ce13f7SAndroid Build Coastguard Worker 
148*03ce13f7SAndroid Build Coastguard Worker   Variable *getPhysicalRegister(RegNumT RegNum,
149*03ce13f7SAndroid Build Coastguard Worker                                 Type Ty = IceType_void) override;
150*03ce13f7SAndroid Build Coastguard Worker   const char *getRegName(RegNumT RegNum, Type Ty) const override;
getRegClassName(RegClass C)151*03ce13f7SAndroid Build Coastguard Worker   static const char *getRegClassName(RegClass C) {
152*03ce13f7SAndroid Build Coastguard Worker     auto ClassNum = static_cast<RegClassX86>(C);
153*03ce13f7SAndroid Build Coastguard Worker     assert(ClassNum < RCX86_NUM);
154*03ce13f7SAndroid Build Coastguard Worker     switch (ClassNum) {
155*03ce13f7SAndroid Build Coastguard Worker     default:
156*03ce13f7SAndroid Build Coastguard Worker       assert(C < RC_Target);
157*03ce13f7SAndroid Build Coastguard Worker       return regClassString(C);
158*03ce13f7SAndroid Build Coastguard Worker     case RCX86_Is64To8:
159*03ce13f7SAndroid Build Coastguard Worker       return "i64to8"; // 64-bit GPR truncable to i8
160*03ce13f7SAndroid Build Coastguard Worker     case RCX86_Is32To8:
161*03ce13f7SAndroid Build Coastguard Worker       return "i32to8"; // 32-bit GPR truncable to i8
162*03ce13f7SAndroid Build Coastguard Worker     case RCX86_Is16To8:
163*03ce13f7SAndroid Build Coastguard Worker       return "i16to8"; // 16-bit GPR truncable to i8
164*03ce13f7SAndroid Build Coastguard Worker     case RCX86_IsTrunc8Rcvr:
165*03ce13f7SAndroid Build Coastguard Worker       return "i8from"; // 8-bit GPR truncable from wider GPRs
166*03ce13f7SAndroid Build Coastguard Worker     case RCX86_IsAhRcvr:
167*03ce13f7SAndroid Build Coastguard Worker       return "i8fromah"; // 8-bit GPR that ah can be assigned to
168*03ce13f7SAndroid Build Coastguard Worker     }
169*03ce13f7SAndroid Build Coastguard Worker   }
170*03ce13f7SAndroid Build Coastguard Worker   SmallBitVector getRegisterSet(RegSetMask Include,
171*03ce13f7SAndroid Build Coastguard Worker                                 RegSetMask Exclude) const override;
172*03ce13f7SAndroid Build Coastguard Worker   const SmallBitVector &
getRegistersForVariable(const Variable * Var)173*03ce13f7SAndroid Build Coastguard Worker   getRegistersForVariable(const Variable *Var) const override {
174*03ce13f7SAndroid Build Coastguard Worker     RegClass RC = Var->getRegClass();
175*03ce13f7SAndroid Build Coastguard Worker     assert(static_cast<RegClassX86>(RC) < RCX86_NUM);
176*03ce13f7SAndroid Build Coastguard Worker     return TypeToRegisterSet[RC];
177*03ce13f7SAndroid Build Coastguard Worker   }
178*03ce13f7SAndroid Build Coastguard Worker 
179*03ce13f7SAndroid Build Coastguard Worker   const SmallBitVector &
getAllRegistersForVariable(const Variable * Var)180*03ce13f7SAndroid Build Coastguard Worker   getAllRegistersForVariable(const Variable *Var) const override {
181*03ce13f7SAndroid Build Coastguard Worker     RegClass RC = Var->getRegClass();
182*03ce13f7SAndroid Build Coastguard Worker     assert(static_cast<RegClassX86>(RC) < RCX86_NUM);
183*03ce13f7SAndroid Build Coastguard Worker     return TypeToRegisterSetUnfiltered[RC];
184*03ce13f7SAndroid Build Coastguard Worker   }
185*03ce13f7SAndroid Build Coastguard Worker 
getAliasesForRegister(RegNumT Reg)186*03ce13f7SAndroid Build Coastguard Worker   const SmallBitVector &getAliasesForRegister(RegNumT Reg) const override {
187*03ce13f7SAndroid Build Coastguard Worker     Reg.assertIsValid();
188*03ce13f7SAndroid Build Coastguard Worker     return RegisterAliases[Reg];
189*03ce13f7SAndroid Build Coastguard Worker   }
190*03ce13f7SAndroid Build Coastguard Worker 
hasFramePointer()191*03ce13f7SAndroid Build Coastguard Worker   bool hasFramePointer() const override { return IsEbpBasedFrame; }
setHasFramePointer()192*03ce13f7SAndroid Build Coastguard Worker   void setHasFramePointer() override { IsEbpBasedFrame = true; }
getStackReg()193*03ce13f7SAndroid Build Coastguard Worker   RegNumT getStackReg() const override { return RegX8664::Reg_rsp; }
getFrameReg()194*03ce13f7SAndroid Build Coastguard Worker   RegNumT getFrameReg() const override { return RegX8664::Reg_rbp; }
getFrameOrStackReg()195*03ce13f7SAndroid Build Coastguard Worker   RegNumT getFrameOrStackReg() const override {
196*03ce13f7SAndroid Build Coastguard Worker     // If the stack pointer needs to be aligned, then the frame pointer is
197*03ce13f7SAndroid Build Coastguard Worker     // unaligned, so always use the stack pointer.
198*03ce13f7SAndroid Build Coastguard Worker     if (needsStackPointerAlignment())
199*03ce13f7SAndroid Build Coastguard Worker       return getStackReg();
200*03ce13f7SAndroid Build Coastguard Worker     return IsEbpBasedFrame ? getFrameReg() : getStackReg();
201*03ce13f7SAndroid Build Coastguard Worker   }
typeWidthInBytesOnStack(Type Ty)202*03ce13f7SAndroid Build Coastguard Worker   size_t typeWidthInBytesOnStack(Type Ty) const override {
203*03ce13f7SAndroid Build Coastguard Worker     // Round up to the next multiple of WordType bytes.
204*03ce13f7SAndroid Build Coastguard Worker     const uint32_t WordSizeInBytes = typeWidthInBytes(WordType);
205*03ce13f7SAndroid Build Coastguard Worker     return Utils::applyAlignment(typeWidthInBytes(Ty), WordSizeInBytes);
206*03ce13f7SAndroid Build Coastguard Worker   }
getStackAlignment()207*03ce13f7SAndroid Build Coastguard Worker   uint32_t getStackAlignment() const override {
208*03ce13f7SAndroid Build Coastguard Worker     return X86_STACK_ALIGNMENT_BYTES;
209*03ce13f7SAndroid Build Coastguard Worker   }
needsStackPointerAlignment()210*03ce13f7SAndroid Build Coastguard Worker   bool needsStackPointerAlignment() const override {
211*03ce13f7SAndroid Build Coastguard Worker     // If the ABI's stack alignment is smaller than the vector size,
212*03ce13f7SAndroid Build Coastguard Worker     // use the (realigned) stack pointer for addressing any stack variables.
213*03ce13f7SAndroid Build Coastguard Worker     return X86_STACK_ALIGNMENT_BYTES < RequiredStackAlignment;
214*03ce13f7SAndroid Build Coastguard Worker   }
reserveFixedAllocaArea(size_t Size,size_t Align)215*03ce13f7SAndroid Build Coastguard Worker   void reserveFixedAllocaArea(size_t Size, size_t Align) override {
216*03ce13f7SAndroid Build Coastguard Worker     FixedAllocaSizeBytes = Size;
217*03ce13f7SAndroid Build Coastguard Worker     assert(llvm::isPowerOf2_32(Align));
218*03ce13f7SAndroid Build Coastguard Worker     FixedAllocaAlignBytes = Align;
219*03ce13f7SAndroid Build Coastguard Worker     PrologEmitsFixedAllocas = true;
220*03ce13f7SAndroid Build Coastguard Worker   }
221*03ce13f7SAndroid Build Coastguard Worker   /// Returns the (negative) offset from ebp/rbp where the fixed Allocas start.
getFrameFixedAllocaOffset()222*03ce13f7SAndroid Build Coastguard Worker   int32_t getFrameFixedAllocaOffset() const override {
223*03ce13f7SAndroid Build Coastguard Worker     return FixedAllocaSizeBytes - (SpillAreaSizeBytes - maxOutArgsSizeBytes());
224*03ce13f7SAndroid Build Coastguard Worker   }
maxOutArgsSizeBytes()225*03ce13f7SAndroid Build Coastguard Worker   virtual uint32_t maxOutArgsSizeBytes() const override {
226*03ce13f7SAndroid Build Coastguard Worker     return MaxOutArgsSizeBytes;
227*03ce13f7SAndroid Build Coastguard Worker   }
updateMaxOutArgsSizeBytes(uint32_t Size)228*03ce13f7SAndroid Build Coastguard Worker   virtual void updateMaxOutArgsSizeBytes(uint32_t Size) {
229*03ce13f7SAndroid Build Coastguard Worker     MaxOutArgsSizeBytes = std::max(MaxOutArgsSizeBytes, Size);
230*03ce13f7SAndroid Build Coastguard Worker   }
231*03ce13f7SAndroid Build Coastguard Worker 
shouldSplitToVariable64On32(Type Ty)232*03ce13f7SAndroid Build Coastguard Worker   bool shouldSplitToVariable64On32(Type Ty) const override { return false; }
233*03ce13f7SAndroid Build Coastguard Worker 
getMinJumpTableSize()234*03ce13f7SAndroid Build Coastguard Worker   SizeT getMinJumpTableSize() const override { return 4; }
235*03ce13f7SAndroid Build Coastguard Worker 
236*03ce13f7SAndroid Build Coastguard Worker   void emitVariable(const Variable *Var) const override;
237*03ce13f7SAndroid Build Coastguard Worker 
238*03ce13f7SAndroid Build Coastguard Worker   void emit(const ConstantInteger32 *C) const final;
239*03ce13f7SAndroid Build Coastguard Worker   void emit(const ConstantInteger64 *C) const final;
240*03ce13f7SAndroid Build Coastguard Worker   void emit(const ConstantFloat *C) const final;
241*03ce13f7SAndroid Build Coastguard Worker   void emit(const ConstantDouble *C) const final;
242*03ce13f7SAndroid Build Coastguard Worker   void emit(const ConstantUndef *C) const final;
243*03ce13f7SAndroid Build Coastguard Worker   void emit(const ConstantRelocatable *C) const final;
244*03ce13f7SAndroid Build Coastguard Worker 
245*03ce13f7SAndroid Build Coastguard Worker   void initNodeForLowering(CfgNode *Node) override;
246*03ce13f7SAndroid Build Coastguard Worker 
247*03ce13f7SAndroid Build Coastguard Worker   void addProlog(CfgNode *Node) override;
248*03ce13f7SAndroid Build Coastguard Worker   void finishArgumentLowering(Variable *Arg, Variable *FramePtr,
249*03ce13f7SAndroid Build Coastguard Worker                               size_t BasicFrameOffset, size_t StackAdjBytes,
250*03ce13f7SAndroid Build Coastguard Worker                               size_t &InArgsSizeBytes);
251*03ce13f7SAndroid Build Coastguard Worker   void addEpilog(CfgNode *Node) override;
252*03ce13f7SAndroid Build Coastguard Worker 
253*03ce13f7SAndroid Build Coastguard Worker   Operand *legalizeUndef(Operand *From, RegNumT RegNum = RegNumT());
254*03ce13f7SAndroid Build Coastguard Worker 
255*03ce13f7SAndroid Build Coastguard Worker protected:
256*03ce13f7SAndroid Build Coastguard Worker   void postLower() override;
257*03ce13f7SAndroid Build Coastguard Worker 
258*03ce13f7SAndroid Build Coastguard Worker   void lowerAlloca(const InstAlloca *Instr) override;
259*03ce13f7SAndroid Build Coastguard Worker   void lowerArguments() override;
260*03ce13f7SAndroid Build Coastguard Worker   void lowerArithmetic(const InstArithmetic *Instr) override;
261*03ce13f7SAndroid Build Coastguard Worker   void lowerAssign(const InstAssign *Instr) override;
262*03ce13f7SAndroid Build Coastguard Worker   void lowerBr(const InstBr *Instr) override;
263*03ce13f7SAndroid Build Coastguard Worker   void lowerBreakpoint(const InstBreakpoint *Instr) override;
264*03ce13f7SAndroid Build Coastguard Worker   void lowerCall(const InstCall *Instr) override;
265*03ce13f7SAndroid Build Coastguard Worker   void lowerCast(const InstCast *Instr) override;
266*03ce13f7SAndroid Build Coastguard Worker   void lowerExtractElement(const InstExtractElement *Instr) override;
267*03ce13f7SAndroid Build Coastguard Worker   void lowerFcmp(const InstFcmp *Instr) override;
268*03ce13f7SAndroid Build Coastguard Worker   void lowerIcmp(const InstIcmp *Instr) override;
269*03ce13f7SAndroid Build Coastguard Worker 
270*03ce13f7SAndroid Build Coastguard Worker   void lowerIntrinsic(const InstIntrinsic *Instr) override;
271*03ce13f7SAndroid Build Coastguard Worker   void lowerInsertElement(const InstInsertElement *Instr) override;
272*03ce13f7SAndroid Build Coastguard Worker   void lowerLoad(const InstLoad *Instr) override;
273*03ce13f7SAndroid Build Coastguard Worker   void lowerPhi(const InstPhi *Instr) override;
274*03ce13f7SAndroid Build Coastguard Worker   void lowerRet(const InstRet *Instr) override;
275*03ce13f7SAndroid Build Coastguard Worker   void lowerSelect(const InstSelect *Instr) override;
276*03ce13f7SAndroid Build Coastguard Worker   void lowerShuffleVector(const InstShuffleVector *Instr) override;
277*03ce13f7SAndroid Build Coastguard Worker   void lowerStore(const InstStore *Instr) override;
278*03ce13f7SAndroid Build Coastguard Worker   void lowerSwitch(const InstSwitch *Instr) override;
279*03ce13f7SAndroid Build Coastguard Worker   void lowerUnreachable(const InstUnreachable *Instr) override;
280*03ce13f7SAndroid Build Coastguard Worker   void lowerOther(const Inst *Instr) override;
281*03ce13f7SAndroid Build Coastguard Worker   void lowerRMW(const InstX86FakeRMW *RMW);
282*03ce13f7SAndroid Build Coastguard Worker   void prelowerPhis() override;
283*03ce13f7SAndroid Build Coastguard Worker   uint32_t getCallStackArgumentsSizeBytes(const CfgVector<Type> &ArgTypes,
284*03ce13f7SAndroid Build Coastguard Worker                                           Type ReturnType);
285*03ce13f7SAndroid Build Coastguard Worker   uint32_t getCallStackArgumentsSizeBytes(const InstCall *Instr) override;
286*03ce13f7SAndroid Build Coastguard Worker   void genTargetHelperCallFor(Inst *Instr) override;
287*03ce13f7SAndroid Build Coastguard Worker 
288*03ce13f7SAndroid Build Coastguard Worker   /// OptAddr wraps all the possible operands that an x86 address might have.
289*03ce13f7SAndroid Build Coastguard Worker   struct OptAddr {
290*03ce13f7SAndroid Build Coastguard Worker     Variable *Base = nullptr;
291*03ce13f7SAndroid Build Coastguard Worker     Variable *Index = nullptr;
292*03ce13f7SAndroid Build Coastguard Worker     uint16_t Shift = 0;
293*03ce13f7SAndroid Build Coastguard Worker     int32_t Offset = 0;
294*03ce13f7SAndroid Build Coastguard Worker     ConstantRelocatable *Relocatable = nullptr;
295*03ce13f7SAndroid Build Coastguard Worker   };
296*03ce13f7SAndroid Build Coastguard Worker 
297*03ce13f7SAndroid Build Coastguard Worker   // Builds information for a canonical address expresion:
298*03ce13f7SAndroid Build Coastguard Worker   //   <Relocatable + Offset>(Base, Index, Shift)
299*03ce13f7SAndroid Build Coastguard Worker   X86OperandMem *computeAddressOpt(const Inst *Instr, Type MemType,
300*03ce13f7SAndroid Build Coastguard Worker                                    Operand *Addr);
301*03ce13f7SAndroid Build Coastguard Worker   void doAddressOptOther() override;
302*03ce13f7SAndroid Build Coastguard Worker   void doAddressOptLoad() override;
303*03ce13f7SAndroid Build Coastguard Worker   void doAddressOptStore() override;
304*03ce13f7SAndroid Build Coastguard Worker   void doAddressOptLoadSubVector() override;
305*03ce13f7SAndroid Build Coastguard Worker   void doAddressOptStoreSubVector() override;
306*03ce13f7SAndroid Build Coastguard Worker   void doMockBoundsCheck(Operand *Opnd) override;
307*03ce13f7SAndroid Build Coastguard Worker 
308*03ce13f7SAndroid Build Coastguard Worker   /// Naive lowering of cmpxchg.
309*03ce13f7SAndroid Build Coastguard Worker   void lowerAtomicCmpxchg(Variable *DestPrev, Operand *Ptr, Operand *Expected,
310*03ce13f7SAndroid Build Coastguard Worker                           Operand *Desired);
311*03ce13f7SAndroid Build Coastguard Worker   /// Attempt a more optimized lowering of cmpxchg. Returns true if optimized.
312*03ce13f7SAndroid Build Coastguard Worker   bool tryOptimizedCmpxchgCmpBr(Variable *DestPrev, Operand *Ptr,
313*03ce13f7SAndroid Build Coastguard Worker                                 Operand *Expected, Operand *Desired);
314*03ce13f7SAndroid Build Coastguard Worker   void lowerAtomicRMW(Variable *Dest, uint32_t Operation, Operand *Ptr,
315*03ce13f7SAndroid Build Coastguard Worker                       Operand *Val);
316*03ce13f7SAndroid Build Coastguard Worker   void lowerCountZeros(bool Cttz, Type Ty, Variable *Dest, Operand *FirstVal,
317*03ce13f7SAndroid Build Coastguard Worker                        Operand *SecondVal);
318*03ce13f7SAndroid Build Coastguard Worker   /// Load from memory for a given type.
319*03ce13f7SAndroid Build Coastguard Worker   void typedLoad(Type Ty, Variable *Dest, Variable *Base, Constant *Offset);
320*03ce13f7SAndroid Build Coastguard Worker   /// Store to memory for a given type.
321*03ce13f7SAndroid Build Coastguard Worker   void typedStore(Type Ty, Variable *Value, Variable *Base, Constant *Offset);
322*03ce13f7SAndroid Build Coastguard Worker   /// Copy memory of given type from Src to Dest using OffsetAmt on both.
323*03ce13f7SAndroid Build Coastguard Worker   void copyMemory(Type Ty, Variable *Dest, Variable *Src, int32_t OffsetAmt);
324*03ce13f7SAndroid Build Coastguard Worker   /// Replace some calls to memcpy with inline instructions.
325*03ce13f7SAndroid Build Coastguard Worker   void lowerMemcpy(Operand *Dest, Operand *Src, Operand *Count);
326*03ce13f7SAndroid Build Coastguard Worker   /// Replace some calls to memmove with inline instructions.
327*03ce13f7SAndroid Build Coastguard Worker   void lowerMemmove(Operand *Dest, Operand *Src, Operand *Count);
328*03ce13f7SAndroid Build Coastguard Worker   /// Replace some calls to memset with inline instructions.
329*03ce13f7SAndroid Build Coastguard Worker   void lowerMemset(Operand *Dest, Operand *Val, Operand *Count);
330*03ce13f7SAndroid Build Coastguard Worker 
331*03ce13f7SAndroid Build Coastguard Worker   /// Lower an indirect jump .
332*03ce13f7SAndroid Build Coastguard Worker   void lowerIndirectJump(Variable *JumpTarget);
333*03ce13f7SAndroid Build Coastguard Worker 
334*03ce13f7SAndroid Build Coastguard Worker   /// Check the comparison is in [Min,Max]. The flags register will be modified
335*03ce13f7SAndroid Build Coastguard Worker   /// with:
336*03ce13f7SAndroid Build Coastguard Worker   ///   - below equal, if in range
337*03ce13f7SAndroid Build Coastguard Worker   ///   - above, set if not in range
338*03ce13f7SAndroid Build Coastguard Worker   /// The index into the range is returned.
339*03ce13f7SAndroid Build Coastguard Worker   Operand *lowerCmpRange(Operand *Comparison, uint64_t Min, uint64_t Max);
340*03ce13f7SAndroid Build Coastguard Worker   /// Lowering of a cluster of switch cases. If the case is not matched control
341*03ce13f7SAndroid Build Coastguard Worker   /// will pass to the default label provided. If the default label is nullptr
342*03ce13f7SAndroid Build Coastguard Worker   /// then control will fall through to the next instruction. DoneCmp should be
343*03ce13f7SAndroid Build Coastguard Worker   /// true if the flags contain the result of a comparison with the Comparison.
344*03ce13f7SAndroid Build Coastguard Worker   void lowerCaseCluster(const CaseCluster &Case, Operand *Src0, bool DoneCmp,
345*03ce13f7SAndroid Build Coastguard Worker                         CfgNode *DefaultLabel = nullptr);
346*03ce13f7SAndroid Build Coastguard Worker 
347*03ce13f7SAndroid Build Coastguard Worker   using LowerBinOp = void (TargetX8664::*)(Variable *, Operand *);
348*03ce13f7SAndroid Build Coastguard Worker   void expandAtomicRMWAsCmpxchg(LowerBinOp op_lo, LowerBinOp op_hi,
349*03ce13f7SAndroid Build Coastguard Worker                                 Variable *Dest, Operand *Ptr, Operand *Val);
350*03ce13f7SAndroid Build Coastguard Worker 
351*03ce13f7SAndroid Build Coastguard Worker   void eliminateNextVectorSextInstruction(Variable *SignExtendedResult);
352*03ce13f7SAndroid Build Coastguard Worker 
353*03ce13f7SAndroid Build Coastguard Worker   void emitStackProbe(size_t StackSizeBytes);
354*03ce13f7SAndroid Build Coastguard Worker 
355*03ce13f7SAndroid Build Coastguard Worker   /// Emit just the call instruction (without argument or return variable
356*03ce13f7SAndroid Build Coastguard Worker   /// processing).
357*03ce13f7SAndroid Build Coastguard Worker   Inst *emitCallToTarget(Operand *CallTarget, Variable *ReturnReg,
358*03ce13f7SAndroid Build Coastguard Worker                          size_t NumVariadicFpArgs = 0);
359*03ce13f7SAndroid Build Coastguard Worker   /// Materialize the moves needed to return a value of the specified type.
360*03ce13f7SAndroid Build Coastguard Worker   Variable *moveReturnValueToRegister(Operand *Value, Type ReturnType);
361*03ce13f7SAndroid Build Coastguard Worker 
362*03ce13f7SAndroid Build Coastguard Worker   /// Emit a jump table to the constant pool.
363*03ce13f7SAndroid Build Coastguard Worker   void emitJumpTable(const Cfg *Func,
364*03ce13f7SAndroid Build Coastguard Worker                      const InstJumpTable *JumpTable) const override;
365*03ce13f7SAndroid Build Coastguard Worker 
366*03ce13f7SAndroid Build Coastguard Worker   /// Emit a fake use of esp to make sure esp stays alive for the entire
367*03ce13f7SAndroid Build Coastguard Worker   /// function. Otherwise some esp adjustments get dead-code eliminated.
keepEspLiveAtExit()368*03ce13f7SAndroid Build Coastguard Worker   void keepEspLiveAtExit() {
369*03ce13f7SAndroid Build Coastguard Worker     Variable *esp =
370*03ce13f7SAndroid Build Coastguard Worker         Func->getTarget()->getPhysicalRegister(getStackReg(), WordType);
371*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstFakeUse>(esp);
372*03ce13f7SAndroid Build Coastguard Worker   }
373*03ce13f7SAndroid Build Coastguard Worker 
374*03ce13f7SAndroid Build Coastguard Worker   /// Operand legalization helpers. To deal with address mode constraints, the
375*03ce13f7SAndroid Build Coastguard Worker   /// helpers will create a new Operand and emit instructions that guarantee
376*03ce13f7SAndroid Build Coastguard Worker   /// that the Operand kind is one of those indicated by the LegalMask (a
377*03ce13f7SAndroid Build Coastguard Worker   /// bitmask of allowed kinds). If the input Operand is known to already meet
378*03ce13f7SAndroid Build Coastguard Worker   /// the constraints, it may be simply returned as the result, without creating
379*03ce13f7SAndroid Build Coastguard Worker   /// any new instructions or operands.
380*03ce13f7SAndroid Build Coastguard Worker   enum OperandLegalization {
381*03ce13f7SAndroid Build Coastguard Worker     Legal_None = 0,
382*03ce13f7SAndroid Build Coastguard Worker     Legal_Reg = 1 << 0, // physical register, not stack location
383*03ce13f7SAndroid Build Coastguard Worker     Legal_Imm = 1 << 1,
384*03ce13f7SAndroid Build Coastguard Worker     Legal_Mem = 1 << 2, // includes [eax+4*ecx] as well as [esp+12]
385*03ce13f7SAndroid Build Coastguard Worker     Legal_Rematerializable = 1 << 3,
386*03ce13f7SAndroid Build Coastguard Worker     Legal_AddrAbs = 1 << 4, // ConstantRelocatable doesn't have to add RebasePtr
387*03ce13f7SAndroid Build Coastguard Worker     Legal_Default = ~(Legal_Rematerializable | Legal_AddrAbs)
388*03ce13f7SAndroid Build Coastguard Worker     // TODO(stichnot): Figure out whether this default works for x86-64.
389*03ce13f7SAndroid Build Coastguard Worker   };
390*03ce13f7SAndroid Build Coastguard Worker   using LegalMask = uint32_t;
391*03ce13f7SAndroid Build Coastguard Worker   Operand *legalize(Operand *From, LegalMask Allowed = Legal_Default,
392*03ce13f7SAndroid Build Coastguard Worker                     RegNumT RegNum = RegNumT());
393*03ce13f7SAndroid Build Coastguard Worker   Variable *legalizeToReg(Operand *From, RegNumT RegNum = RegNumT());
394*03ce13f7SAndroid Build Coastguard Worker   /// Legalize the first source operand for use in the cmp instruction.
395*03ce13f7SAndroid Build Coastguard Worker   Operand *legalizeSrc0ForCmp(Operand *Src0, Operand *Src1);
396*03ce13f7SAndroid Build Coastguard Worker   /// Turn a pointer operand into a memory operand that can be used by a real
397*03ce13f7SAndroid Build Coastguard Worker   /// load/store operation. Legalizes the operand as well. This is a nop if the
398*03ce13f7SAndroid Build Coastguard Worker   /// operand is already a legal memory operand.
399*03ce13f7SAndroid Build Coastguard Worker   X86OperandMem *formMemoryOperand(Operand *Ptr, Type Ty,
400*03ce13f7SAndroid Build Coastguard Worker                                    bool DoLegalize = true);
401*03ce13f7SAndroid Build Coastguard Worker 
402*03ce13f7SAndroid Build Coastguard Worker   Variable *makeReg(Type Ty, RegNumT RegNum = RegNumT());
403*03ce13f7SAndroid Build Coastguard Worker   static Type stackSlotType();
404*03ce13f7SAndroid Build Coastguard Worker 
405*03ce13f7SAndroid Build Coastguard Worker   static constexpr uint32_t NoSizeLimit = 0;
406*03ce13f7SAndroid Build Coastguard Worker   /// Returns the largest type which is equal to or larger than Size bytes. The
407*03ce13f7SAndroid Build Coastguard Worker   /// type is suitable for copying memory i.e. a load and store will be a single
408*03ce13f7SAndroid Build Coastguard Worker   /// instruction (for example x86 will get f64 not i64).
409*03ce13f7SAndroid Build Coastguard Worker   static Type largestTypeInSize(uint32_t Size, uint32_t MaxSize = NoSizeLimit);
410*03ce13f7SAndroid Build Coastguard Worker   /// Returns the smallest type which is equal to or larger than Size bytes. If
411*03ce13f7SAndroid Build Coastguard Worker   /// one doesn't exist then the largest type smaller than Size bytes is
412*03ce13f7SAndroid Build Coastguard Worker   /// returned. The type is suitable for memory copies as described at
413*03ce13f7SAndroid Build Coastguard Worker   /// largestTypeInSize.
414*03ce13f7SAndroid Build Coastguard Worker   static Type firstTypeThatFitsSize(uint32_t Size,
415*03ce13f7SAndroid Build Coastguard Worker                                     uint32_t MaxSize = NoSizeLimit);
416*03ce13f7SAndroid Build Coastguard Worker 
417*03ce13f7SAndroid Build Coastguard Worker   Variable *copyToReg8(Operand *Src, RegNumT RegNum = RegNumT());
418*03ce13f7SAndroid Build Coastguard Worker   Variable *copyToReg(Operand *Src, RegNumT RegNum = RegNumT());
419*03ce13f7SAndroid Build Coastguard Worker 
420*03ce13f7SAndroid Build Coastguard Worker   /// Returns a register containing all zeros, without affecting the FLAGS
421*03ce13f7SAndroid Build Coastguard Worker   /// register, using the best instruction for the type.
422*03ce13f7SAndroid Build Coastguard Worker   Variable *makeZeroedRegister(Type Ty, RegNumT RegNum = RegNumT());
423*03ce13f7SAndroid Build Coastguard Worker 
424*03ce13f7SAndroid Build Coastguard Worker   /// \name Returns a vector in a register with the given constant entries.
425*03ce13f7SAndroid Build Coastguard Worker   /// @{
426*03ce13f7SAndroid Build Coastguard Worker   Variable *makeVectorOfZeros(Type Ty, RegNumT RegNum = RegNumT());
427*03ce13f7SAndroid Build Coastguard Worker   Variable *makeVectorOfOnes(Type Ty, RegNumT RegNum = RegNumT());
428*03ce13f7SAndroid Build Coastguard Worker   Variable *makeVectorOfMinusOnes(Type Ty, RegNumT RegNum = RegNumT());
429*03ce13f7SAndroid Build Coastguard Worker   Variable *makeVectorOfHighOrderBits(Type Ty, RegNumT RegNum = RegNumT());
430*03ce13f7SAndroid Build Coastguard Worker   Variable *makeVectorOfFabsMask(Type Ty, RegNumT RegNum = RegNumT());
431*03ce13f7SAndroid Build Coastguard Worker   /// @}
432*03ce13f7SAndroid Build Coastguard Worker 
433*03ce13f7SAndroid Build Coastguard Worker   /// Return a memory operand corresponding to a stack allocated Variable.
434*03ce13f7SAndroid Build Coastguard Worker   X86OperandMem *getMemoryOperandForStackSlot(Type Ty, Variable *Slot,
435*03ce13f7SAndroid Build Coastguard Worker                                               uint32_t Offset = 0);
436*03ce13f7SAndroid Build Coastguard Worker 
437*03ce13f7SAndroid Build Coastguard Worker   /// The following are helpers that insert lowered x86 instructions with
438*03ce13f7SAndroid Build Coastguard Worker   /// minimal syntactic overhead, so that the lowering code can look as close to
439*03ce13f7SAndroid Build Coastguard Worker   /// assembly as practical.
_adc(Variable * Dest,Operand * Src0)440*03ce13f7SAndroid Build Coastguard Worker   void _adc(Variable *Dest, Operand *Src0) {
441*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Adc>(Dest, Src0);
442*03ce13f7SAndroid Build Coastguard Worker   }
_adc_rmw(X86OperandMem * DestSrc0,Operand * Src1)443*03ce13f7SAndroid Build Coastguard Worker   void _adc_rmw(X86OperandMem *DestSrc0, Operand *Src1) {
444*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::AdcRMW>(DestSrc0, Src1);
445*03ce13f7SAndroid Build Coastguard Worker   }
_add(Variable * Dest,Operand * Src0)446*03ce13f7SAndroid Build Coastguard Worker   void _add(Variable *Dest, Operand *Src0) {
447*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Add>(Dest, Src0);
448*03ce13f7SAndroid Build Coastguard Worker   }
_add_rmw(X86OperandMem * DestSrc0,Operand * Src1)449*03ce13f7SAndroid Build Coastguard Worker   void _add_rmw(X86OperandMem *DestSrc0, Operand *Src1) {
450*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::AddRMW>(DestSrc0, Src1);
451*03ce13f7SAndroid Build Coastguard Worker   }
_addps(Variable * Dest,Operand * Src0)452*03ce13f7SAndroid Build Coastguard Worker   void _addps(Variable *Dest, Operand *Src0) {
453*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Addps>(Dest, Src0);
454*03ce13f7SAndroid Build Coastguard Worker   }
_addss(Variable * Dest,Operand * Src0)455*03ce13f7SAndroid Build Coastguard Worker   void _addss(Variable *Dest, Operand *Src0) {
456*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Addss>(Dest, Src0);
457*03ce13f7SAndroid Build Coastguard Worker   }
458*03ce13f7SAndroid Build Coastguard Worker   void _add_sp(Operand *Adjustment);
_and(Variable * Dest,Operand * Src0)459*03ce13f7SAndroid Build Coastguard Worker   void _and(Variable *Dest, Operand *Src0) {
460*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::And>(Dest, Src0);
461*03ce13f7SAndroid Build Coastguard Worker   }
_andnps(Variable * Dest,Operand * Src0)462*03ce13f7SAndroid Build Coastguard Worker   void _andnps(Variable *Dest, Operand *Src0) {
463*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Andnps>(Dest, Src0);
464*03ce13f7SAndroid Build Coastguard Worker   }
_andps(Variable * Dest,Operand * Src0)465*03ce13f7SAndroid Build Coastguard Worker   void _andps(Variable *Dest, Operand *Src0) {
466*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Andps>(Dest, Src0);
467*03ce13f7SAndroid Build Coastguard Worker   }
_and_rmw(X86OperandMem * DestSrc0,Operand * Src1)468*03ce13f7SAndroid Build Coastguard Worker   void _and_rmw(X86OperandMem *DestSrc0, Operand *Src1) {
469*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::AndRMW>(DestSrc0, Src1);
470*03ce13f7SAndroid Build Coastguard Worker   }
_blendvps(Variable * Dest,Operand * Src0,Operand * Src1)471*03ce13f7SAndroid Build Coastguard Worker   void _blendvps(Variable *Dest, Operand *Src0, Operand *Src1) {
472*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Blendvps>(Dest, Src0, Src1);
473*03ce13f7SAndroid Build Coastguard Worker   }
_br(BrCond Condition,CfgNode * TargetTrue,CfgNode * TargetFalse)474*03ce13f7SAndroid Build Coastguard Worker   void _br(BrCond Condition, CfgNode *TargetTrue, CfgNode *TargetFalse) {
475*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstX86Br>(TargetTrue, TargetFalse, Condition,
476*03ce13f7SAndroid Build Coastguard Worker                               InstX86Br::Far);
477*03ce13f7SAndroid Build Coastguard Worker   }
_br(CfgNode * Target)478*03ce13f7SAndroid Build Coastguard Worker   void _br(CfgNode *Target) {
479*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstX86Br>(Target, InstX86Br::Far);
480*03ce13f7SAndroid Build Coastguard Worker   }
_br(BrCond Condition,CfgNode * Target)481*03ce13f7SAndroid Build Coastguard Worker   void _br(BrCond Condition, CfgNode *Target) {
482*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstX86Br>(Target, Condition, InstX86Br::Far);
483*03ce13f7SAndroid Build Coastguard Worker   }
484*03ce13f7SAndroid Build Coastguard Worker   void _br(BrCond Condition, InstX86Label *Label,
485*03ce13f7SAndroid Build Coastguard Worker            InstX86Br::Mode Kind = InstX86Br::Near) {
486*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstX86Br>(Label, Condition, Kind);
487*03ce13f7SAndroid Build Coastguard Worker   }
_bsf(Variable * Dest,Operand * Src0)488*03ce13f7SAndroid Build Coastguard Worker   void _bsf(Variable *Dest, Operand *Src0) {
489*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Bsf>(Dest, Src0);
490*03ce13f7SAndroid Build Coastguard Worker   }
_bsr(Variable * Dest,Operand * Src0)491*03ce13f7SAndroid Build Coastguard Worker   void _bsr(Variable *Dest, Operand *Src0) {
492*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Bsr>(Dest, Src0);
493*03ce13f7SAndroid Build Coastguard Worker   }
_bswap(Variable * SrcDest)494*03ce13f7SAndroid Build Coastguard Worker   void _bswap(Variable *SrcDest) { Context.insert<Insts::Bswap>(SrcDest); }
_cbwdq(Variable * Dest,Operand * Src0)495*03ce13f7SAndroid Build Coastguard Worker   void _cbwdq(Variable *Dest, Operand *Src0) {
496*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Cbwdq>(Dest, Src0);
497*03ce13f7SAndroid Build Coastguard Worker   }
_cmov(Variable * Dest,Operand * Src0,BrCond Condition)498*03ce13f7SAndroid Build Coastguard Worker   void _cmov(Variable *Dest, Operand *Src0, BrCond Condition) {
499*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Cmov>(Dest, Src0, Condition);
500*03ce13f7SAndroid Build Coastguard Worker   }
_cmp(Operand * Src0,Operand * Src1)501*03ce13f7SAndroid Build Coastguard Worker   void _cmp(Operand *Src0, Operand *Src1) {
502*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Icmp>(Src0, Src1);
503*03ce13f7SAndroid Build Coastguard Worker   }
_cmpps(Variable * Dest,Operand * Src0,CmppsCond Condition)504*03ce13f7SAndroid Build Coastguard Worker   void _cmpps(Variable *Dest, Operand *Src0, CmppsCond Condition) {
505*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Cmpps>(Dest, Src0, Condition);
506*03ce13f7SAndroid Build Coastguard Worker   }
_cmpxchg(Operand * DestOrAddr,Variable * Eax,Variable * Desired,bool Locked)507*03ce13f7SAndroid Build Coastguard Worker   void _cmpxchg(Operand *DestOrAddr, Variable *Eax, Variable *Desired,
508*03ce13f7SAndroid Build Coastguard Worker                 bool Locked) {
509*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Cmpxchg>(DestOrAddr, Eax, Desired, Locked);
510*03ce13f7SAndroid Build Coastguard Worker     // Mark eax as possibly modified by cmpxchg.
511*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstFakeDef>(Eax, llvm::dyn_cast<Variable>(DestOrAddr));
512*03ce13f7SAndroid Build Coastguard Worker     _set_dest_redefined();
513*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstFakeUse>(Eax);
514*03ce13f7SAndroid Build Coastguard Worker   }
_cmpxchg8b(X86OperandMem * Addr,Variable * Edx,Variable * Eax,Variable * Ecx,Variable * Ebx,bool Locked)515*03ce13f7SAndroid Build Coastguard Worker   void _cmpxchg8b(X86OperandMem *Addr, Variable *Edx, Variable *Eax,
516*03ce13f7SAndroid Build Coastguard Worker                   Variable *Ecx, Variable *Ebx, bool Locked) {
517*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Cmpxchg8b>(Addr, Edx, Eax, Ecx, Ebx, Locked);
518*03ce13f7SAndroid Build Coastguard Worker     // Mark edx, and eax as possibly modified by cmpxchg8b.
519*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstFakeDef>(Edx);
520*03ce13f7SAndroid Build Coastguard Worker     _set_dest_redefined();
521*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstFakeUse>(Edx);
522*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstFakeDef>(Eax);
523*03ce13f7SAndroid Build Coastguard Worker     _set_dest_redefined();
524*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstFakeUse>(Eax);
525*03ce13f7SAndroid Build Coastguard Worker   }
_cvt(Variable * Dest,Operand * Src0,Insts::Cvt::CvtVariant Variant)526*03ce13f7SAndroid Build Coastguard Worker   void _cvt(Variable *Dest, Operand *Src0, Insts::Cvt::CvtVariant Variant) {
527*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Cvt>(Dest, Src0, Variant);
528*03ce13f7SAndroid Build Coastguard Worker   }
_round(Variable * Dest,Operand * Src0,Operand * Imm)529*03ce13f7SAndroid Build Coastguard Worker   void _round(Variable *Dest, Operand *Src0, Operand *Imm) {
530*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Round>(Dest, Src0, Imm);
531*03ce13f7SAndroid Build Coastguard Worker   }
_div(Variable * Dest,Operand * Src0,Operand * Src1)532*03ce13f7SAndroid Build Coastguard Worker   void _div(Variable *Dest, Operand *Src0, Operand *Src1) {
533*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Div>(Dest, Src0, Src1);
534*03ce13f7SAndroid Build Coastguard Worker   }
_divps(Variable * Dest,Operand * Src0)535*03ce13f7SAndroid Build Coastguard Worker   void _divps(Variable *Dest, Operand *Src0) {
536*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Divps>(Dest, Src0);
537*03ce13f7SAndroid Build Coastguard Worker   }
_divss(Variable * Dest,Operand * Src0)538*03ce13f7SAndroid Build Coastguard Worker   void _divss(Variable *Dest, Operand *Src0) {
539*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Divss>(Dest, Src0);
540*03ce13f7SAndroid Build Coastguard Worker   }
_idiv(Variable * Dest,Operand * Src0,Operand * Src1)541*03ce13f7SAndroid Build Coastguard Worker   void _idiv(Variable *Dest, Operand *Src0, Operand *Src1) {
542*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Idiv>(Dest, Src0, Src1);
543*03ce13f7SAndroid Build Coastguard Worker   }
_imul(Variable * Dest,Operand * Src0)544*03ce13f7SAndroid Build Coastguard Worker   void _imul(Variable *Dest, Operand *Src0) {
545*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Imul>(Dest, Src0);
546*03ce13f7SAndroid Build Coastguard Worker   }
_imul_imm(Variable * Dest,Operand * Src0,Constant * Imm)547*03ce13f7SAndroid Build Coastguard Worker   void _imul_imm(Variable *Dest, Operand *Src0, Constant *Imm) {
548*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::ImulImm>(Dest, Src0, Imm);
549*03ce13f7SAndroid Build Coastguard Worker   }
_insertps(Variable * Dest,Operand * Src0,Operand * Src1)550*03ce13f7SAndroid Build Coastguard Worker   void _insertps(Variable *Dest, Operand *Src0, Operand *Src1) {
551*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Insertps>(Dest, Src0, Src1);
552*03ce13f7SAndroid Build Coastguard Worker   }
_int3()553*03ce13f7SAndroid Build Coastguard Worker   void _int3() { Context.insert<Insts::Int3>(); }
_jmp(Operand * Target)554*03ce13f7SAndroid Build Coastguard Worker   void _jmp(Operand *Target) { Context.insert<Insts::Jmp>(Target); }
_lea(Variable * Dest,Operand * Src0)555*03ce13f7SAndroid Build Coastguard Worker   void _lea(Variable *Dest, Operand *Src0) {
556*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Lea>(Dest, Src0);
557*03ce13f7SAndroid Build Coastguard Worker   }
558*03ce13f7SAndroid Build Coastguard Worker   void _link_bp();
559*03ce13f7SAndroid Build Coastguard Worker   void _push_reg(RegNumT RegNum);
560*03ce13f7SAndroid Build Coastguard Worker   void _pop_reg(RegNumT RegNum);
_mfence()561*03ce13f7SAndroid Build Coastguard Worker   void _mfence() { Context.insert<Insts::Mfence>(); }
562*03ce13f7SAndroid Build Coastguard Worker   /// Moves can be used to redefine registers, creating "partial kills" for
563*03ce13f7SAndroid Build Coastguard Worker   /// liveness.  Mark where moves are used in this way.
564*03ce13f7SAndroid Build Coastguard Worker   void _redefined(Inst *MovInst, bool IsRedefinition = true) {
565*03ce13f7SAndroid Build Coastguard Worker     if (IsRedefinition)
566*03ce13f7SAndroid Build Coastguard Worker       MovInst->setDestRedefined();
567*03ce13f7SAndroid Build Coastguard Worker   }
568*03ce13f7SAndroid Build Coastguard Worker   /// If Dest=nullptr is passed in, then a new variable is created, marked as
569*03ce13f7SAndroid Build Coastguard Worker   /// infinite register allocation weight, and returned through the in/out Dest
570*03ce13f7SAndroid Build Coastguard Worker   /// argument.
571*03ce13f7SAndroid Build Coastguard Worker   Insts::Mov *_mov(Variable *&Dest, Operand *Src0, RegNumT RegNum = RegNumT()) {
572*03ce13f7SAndroid Build Coastguard Worker     if (Dest == nullptr)
573*03ce13f7SAndroid Build Coastguard Worker       Dest = makeReg(Src0->getType(), RegNum);
574*03ce13f7SAndroid Build Coastguard Worker     return Context.insert<Insts::Mov>(Dest, Src0);
575*03ce13f7SAndroid Build Coastguard Worker   }
576*03ce13f7SAndroid Build Coastguard Worker   void _mov_sp(Operand *NewValue);
_movp(Variable * Dest,Operand * Src0)577*03ce13f7SAndroid Build Coastguard Worker   Insts::Movp *_movp(Variable *Dest, Operand *Src0) {
578*03ce13f7SAndroid Build Coastguard Worker     return Context.insert<Insts::Movp>(Dest, Src0);
579*03ce13f7SAndroid Build Coastguard Worker   }
_movd(Variable * Dest,Operand * Src0)580*03ce13f7SAndroid Build Coastguard Worker   void _movd(Variable *Dest, Operand *Src0) {
581*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Movd>(Dest, Src0);
582*03ce13f7SAndroid Build Coastguard Worker   }
_movq(Variable * Dest,Operand * Src0)583*03ce13f7SAndroid Build Coastguard Worker   void _movq(Variable *Dest, Operand *Src0) {
584*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Movq>(Dest, Src0);
585*03ce13f7SAndroid Build Coastguard Worker   }
_movss(Variable * Dest,Variable * Src0)586*03ce13f7SAndroid Build Coastguard Worker   void _movss(Variable *Dest, Variable *Src0) {
587*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::MovssRegs>(Dest, Src0);
588*03ce13f7SAndroid Build Coastguard Worker   }
_movsx(Variable * Dest,Operand * Src0)589*03ce13f7SAndroid Build Coastguard Worker   void _movsx(Variable *Dest, Operand *Src0) {
590*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Movsx>(Dest, Src0);
591*03ce13f7SAndroid Build Coastguard Worker   }
_movzx(Variable * Dest,Operand * Src0)592*03ce13f7SAndroid Build Coastguard Worker   Insts::Movzx *_movzx(Variable *Dest, Operand *Src0) {
593*03ce13f7SAndroid Build Coastguard Worker     return Context.insert<Insts::Movzx>(Dest, Src0);
594*03ce13f7SAndroid Build Coastguard Worker   }
_maxss(Variable * Dest,Operand * Src0)595*03ce13f7SAndroid Build Coastguard Worker   void _maxss(Variable *Dest, Operand *Src0) {
596*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Maxss>(Dest, Src0);
597*03ce13f7SAndroid Build Coastguard Worker   }
_minss(Variable * Dest,Operand * Src0)598*03ce13f7SAndroid Build Coastguard Worker   void _minss(Variable *Dest, Operand *Src0) {
599*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Minss>(Dest, Src0);
600*03ce13f7SAndroid Build Coastguard Worker   }
_maxps(Variable * Dest,Operand * Src0)601*03ce13f7SAndroid Build Coastguard Worker   void _maxps(Variable *Dest, Operand *Src0) {
602*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Maxps>(Dest, Src0);
603*03ce13f7SAndroid Build Coastguard Worker   }
_minps(Variable * Dest,Operand * Src0)604*03ce13f7SAndroid Build Coastguard Worker   void _minps(Variable *Dest, Operand *Src0) {
605*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Minps>(Dest, Src0);
606*03ce13f7SAndroid Build Coastguard Worker   }
_mul(Variable * Dest,Variable * Src0,Operand * Src1)607*03ce13f7SAndroid Build Coastguard Worker   void _mul(Variable *Dest, Variable *Src0, Operand *Src1) {
608*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Mul>(Dest, Src0, Src1);
609*03ce13f7SAndroid Build Coastguard Worker   }
_mulps(Variable * Dest,Operand * Src0)610*03ce13f7SAndroid Build Coastguard Worker   void _mulps(Variable *Dest, Operand *Src0) {
611*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Mulps>(Dest, Src0);
612*03ce13f7SAndroid Build Coastguard Worker   }
_mulss(Variable * Dest,Operand * Src0)613*03ce13f7SAndroid Build Coastguard Worker   void _mulss(Variable *Dest, Operand *Src0) {
614*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Mulss>(Dest, Src0);
615*03ce13f7SAndroid Build Coastguard Worker   }
_neg(Variable * SrcDest)616*03ce13f7SAndroid Build Coastguard Worker   void _neg(Variable *SrcDest) { Context.insert<Insts::Neg>(SrcDest); }
_nop(SizeT Variant)617*03ce13f7SAndroid Build Coastguard Worker   void _nop(SizeT Variant) { Context.insert<Insts::Nop>(Variant); }
_or(Variable * Dest,Operand * Src0)618*03ce13f7SAndroid Build Coastguard Worker   void _or(Variable *Dest, Operand *Src0) {
619*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Or>(Dest, Src0);
620*03ce13f7SAndroid Build Coastguard Worker   }
_orps(Variable * Dest,Operand * Src0)621*03ce13f7SAndroid Build Coastguard Worker   void _orps(Variable *Dest, Operand *Src0) {
622*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Orps>(Dest, Src0);
623*03ce13f7SAndroid Build Coastguard Worker   }
_or_rmw(X86OperandMem * DestSrc0,Operand * Src1)624*03ce13f7SAndroid Build Coastguard Worker   void _or_rmw(X86OperandMem *DestSrc0, Operand *Src1) {
625*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::OrRMW>(DestSrc0, Src1);
626*03ce13f7SAndroid Build Coastguard Worker   }
_padd(Variable * Dest,Operand * Src0)627*03ce13f7SAndroid Build Coastguard Worker   void _padd(Variable *Dest, Operand *Src0) {
628*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Padd>(Dest, Src0);
629*03ce13f7SAndroid Build Coastguard Worker   }
_padds(Variable * Dest,Operand * Src0)630*03ce13f7SAndroid Build Coastguard Worker   void _padds(Variable *Dest, Operand *Src0) {
631*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Padds>(Dest, Src0);
632*03ce13f7SAndroid Build Coastguard Worker   }
_paddus(Variable * Dest,Operand * Src0)633*03ce13f7SAndroid Build Coastguard Worker   void _paddus(Variable *Dest, Operand *Src0) {
634*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Paddus>(Dest, Src0);
635*03ce13f7SAndroid Build Coastguard Worker   }
_pand(Variable * Dest,Operand * Src0)636*03ce13f7SAndroid Build Coastguard Worker   void _pand(Variable *Dest, Operand *Src0) {
637*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Pand>(Dest, Src0);
638*03ce13f7SAndroid Build Coastguard Worker   }
_pandn(Variable * Dest,Operand * Src0)639*03ce13f7SAndroid Build Coastguard Worker   void _pandn(Variable *Dest, Operand *Src0) {
640*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Pandn>(Dest, Src0);
641*03ce13f7SAndroid Build Coastguard Worker   }
_pblendvb(Variable * Dest,Operand * Src0,Operand * Src1)642*03ce13f7SAndroid Build Coastguard Worker   void _pblendvb(Variable *Dest, Operand *Src0, Operand *Src1) {
643*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Pblendvb>(Dest, Src0, Src1);
644*03ce13f7SAndroid Build Coastguard Worker   }
645*03ce13f7SAndroid Build Coastguard Worker   void _pcmpeq(Variable *Dest, Operand *Src0,
646*03ce13f7SAndroid Build Coastguard Worker                Type ArithmeticTypeOverride = IceType_void) {
647*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Pcmpeq>(Dest, Src0, ArithmeticTypeOverride);
648*03ce13f7SAndroid Build Coastguard Worker   }
_pcmpgt(Variable * Dest,Operand * Src0)649*03ce13f7SAndroid Build Coastguard Worker   void _pcmpgt(Variable *Dest, Operand *Src0) {
650*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Pcmpgt>(Dest, Src0);
651*03ce13f7SAndroid Build Coastguard Worker   }
_pextr(Variable * Dest,Operand * Src0,Operand * Src1)652*03ce13f7SAndroid Build Coastguard Worker   void _pextr(Variable *Dest, Operand *Src0, Operand *Src1) {
653*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Pextr>(Dest, Src0, Src1);
654*03ce13f7SAndroid Build Coastguard Worker   }
_pinsr(Variable * Dest,Operand * Src0,Operand * Src1)655*03ce13f7SAndroid Build Coastguard Worker   void _pinsr(Variable *Dest, Operand *Src0, Operand *Src1) {
656*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Pinsr>(Dest, Src0, Src1);
657*03ce13f7SAndroid Build Coastguard Worker   }
_pmull(Variable * Dest,Operand * Src0)658*03ce13f7SAndroid Build Coastguard Worker   void _pmull(Variable *Dest, Operand *Src0) {
659*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Pmull>(Dest, Src0);
660*03ce13f7SAndroid Build Coastguard Worker   }
_pmulhw(Variable * Dest,Operand * Src0)661*03ce13f7SAndroid Build Coastguard Worker   void _pmulhw(Variable *Dest, Operand *Src0) {
662*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Pmulhw>(Dest, Src0);
663*03ce13f7SAndroid Build Coastguard Worker   }
_pmulhuw(Variable * Dest,Operand * Src0)664*03ce13f7SAndroid Build Coastguard Worker   void _pmulhuw(Variable *Dest, Operand *Src0) {
665*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Pmulhuw>(Dest, Src0);
666*03ce13f7SAndroid Build Coastguard Worker   }
_pmaddwd(Variable * Dest,Operand * Src0)667*03ce13f7SAndroid Build Coastguard Worker   void _pmaddwd(Variable *Dest, Operand *Src0) {
668*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Pmaddwd>(Dest, Src0);
669*03ce13f7SAndroid Build Coastguard Worker   }
_pmuludq(Variable * Dest,Operand * Src0)670*03ce13f7SAndroid Build Coastguard Worker   void _pmuludq(Variable *Dest, Operand *Src0) {
671*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Pmuludq>(Dest, Src0);
672*03ce13f7SAndroid Build Coastguard Worker   }
_pop(Variable * Dest)673*03ce13f7SAndroid Build Coastguard Worker   void _pop(Variable *Dest) { Context.insert<Insts::Pop>(Dest); }
_por(Variable * Dest,Operand * Src0)674*03ce13f7SAndroid Build Coastguard Worker   void _por(Variable *Dest, Operand *Src0) {
675*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Por>(Dest, Src0);
676*03ce13f7SAndroid Build Coastguard Worker   }
_punpckl(Variable * Dest,Operand * Src0)677*03ce13f7SAndroid Build Coastguard Worker   void _punpckl(Variable *Dest, Operand *Src0) {
678*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Punpckl>(Dest, Src0);
679*03ce13f7SAndroid Build Coastguard Worker   }
_punpckh(Variable * Dest,Operand * Src0)680*03ce13f7SAndroid Build Coastguard Worker   void _punpckh(Variable *Dest, Operand *Src0) {
681*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Punpckh>(Dest, Src0);
682*03ce13f7SAndroid Build Coastguard Worker   }
_packss(Variable * Dest,Operand * Src0)683*03ce13f7SAndroid Build Coastguard Worker   void _packss(Variable *Dest, Operand *Src0) {
684*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Packss>(Dest, Src0);
685*03ce13f7SAndroid Build Coastguard Worker   }
_packus(Variable * Dest,Operand * Src0)686*03ce13f7SAndroid Build Coastguard Worker   void _packus(Variable *Dest, Operand *Src0) {
687*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Packus>(Dest, Src0);
688*03ce13f7SAndroid Build Coastguard Worker   }
_pshufb(Variable * Dest,Operand * Src0)689*03ce13f7SAndroid Build Coastguard Worker   void _pshufb(Variable *Dest, Operand *Src0) {
690*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Pshufb>(Dest, Src0);
691*03ce13f7SAndroid Build Coastguard Worker   }
_pshufd(Variable * Dest,Operand * Src0,Operand * Src1)692*03ce13f7SAndroid Build Coastguard Worker   void _pshufd(Variable *Dest, Operand *Src0, Operand *Src1) {
693*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Pshufd>(Dest, Src0, Src1);
694*03ce13f7SAndroid Build Coastguard Worker   }
_psll(Variable * Dest,Operand * Src0)695*03ce13f7SAndroid Build Coastguard Worker   void _psll(Variable *Dest, Operand *Src0) {
696*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Psll>(Dest, Src0);
697*03ce13f7SAndroid Build Coastguard Worker   }
_psra(Variable * Dest,Operand * Src0)698*03ce13f7SAndroid Build Coastguard Worker   void _psra(Variable *Dest, Operand *Src0) {
699*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Psra>(Dest, Src0);
700*03ce13f7SAndroid Build Coastguard Worker   }
_psrl(Variable * Dest,Operand * Src0)701*03ce13f7SAndroid Build Coastguard Worker   void _psrl(Variable *Dest, Operand *Src0) {
702*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Psrl>(Dest, Src0);
703*03ce13f7SAndroid Build Coastguard Worker   }
_psub(Variable * Dest,Operand * Src0)704*03ce13f7SAndroid Build Coastguard Worker   void _psub(Variable *Dest, Operand *Src0) {
705*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Psub>(Dest, Src0);
706*03ce13f7SAndroid Build Coastguard Worker   }
_psubs(Variable * Dest,Operand * Src0)707*03ce13f7SAndroid Build Coastguard Worker   void _psubs(Variable *Dest, Operand *Src0) {
708*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Psubs>(Dest, Src0);
709*03ce13f7SAndroid Build Coastguard Worker   }
_psubus(Variable * Dest,Operand * Src0)710*03ce13f7SAndroid Build Coastguard Worker   void _psubus(Variable *Dest, Operand *Src0) {
711*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Psubus>(Dest, Src0);
712*03ce13f7SAndroid Build Coastguard Worker   }
_push(Operand * Src0)713*03ce13f7SAndroid Build Coastguard Worker   void _push(Operand *Src0) { Context.insert<Insts::Push>(Src0); }
_pxor(Variable * Dest,Operand * Src0)714*03ce13f7SAndroid Build Coastguard Worker   void _pxor(Variable *Dest, Operand *Src0) {
715*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Pxor>(Dest, Src0);
716*03ce13f7SAndroid Build Coastguard Worker   }
717*03ce13f7SAndroid Build Coastguard Worker   void _ret(Variable *Src0 = nullptr) { Context.insert<Insts::Ret>(Src0); }
_rol(Variable * Dest,Operand * Src0)718*03ce13f7SAndroid Build Coastguard Worker   void _rol(Variable *Dest, Operand *Src0) {
719*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Rol>(Dest, Src0);
720*03ce13f7SAndroid Build Coastguard Worker   }
_round(Variable * Dest,Operand * Src,Constant * Imm)721*03ce13f7SAndroid Build Coastguard Worker   void _round(Variable *Dest, Operand *Src, Constant *Imm) {
722*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Round>(Dest, Src, Imm);
723*03ce13f7SAndroid Build Coastguard Worker   }
_sar(Variable * Dest,Operand * Src0)724*03ce13f7SAndroid Build Coastguard Worker   void _sar(Variable *Dest, Operand *Src0) {
725*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Sar>(Dest, Src0);
726*03ce13f7SAndroid Build Coastguard Worker   }
_sbb(Variable * Dest,Operand * Src0)727*03ce13f7SAndroid Build Coastguard Worker   void _sbb(Variable *Dest, Operand *Src0) {
728*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Sbb>(Dest, Src0);
729*03ce13f7SAndroid Build Coastguard Worker   }
_sbb_rmw(X86OperandMem * DestSrc0,Operand * Src1)730*03ce13f7SAndroid Build Coastguard Worker   void _sbb_rmw(X86OperandMem *DestSrc0, Operand *Src1) {
731*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::SbbRMW>(DestSrc0, Src1);
732*03ce13f7SAndroid Build Coastguard Worker   }
_setcc(Variable * Dest,BrCond Condition)733*03ce13f7SAndroid Build Coastguard Worker   void _setcc(Variable *Dest, BrCond Condition) {
734*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Setcc>(Dest, Condition);
735*03ce13f7SAndroid Build Coastguard Worker   }
_shl(Variable * Dest,Operand * Src0)736*03ce13f7SAndroid Build Coastguard Worker   void _shl(Variable *Dest, Operand *Src0) {
737*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Shl>(Dest, Src0);
738*03ce13f7SAndroid Build Coastguard Worker   }
_shld(Variable * Dest,Variable * Src0,Operand * Src1)739*03ce13f7SAndroid Build Coastguard Worker   void _shld(Variable *Dest, Variable *Src0, Operand *Src1) {
740*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Shld>(Dest, Src0, Src1);
741*03ce13f7SAndroid Build Coastguard Worker   }
_shr(Variable * Dest,Operand * Src0)742*03ce13f7SAndroid Build Coastguard Worker   void _shr(Variable *Dest, Operand *Src0) {
743*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Shr>(Dest, Src0);
744*03ce13f7SAndroid Build Coastguard Worker   }
_shrd(Variable * Dest,Variable * Src0,Operand * Src1)745*03ce13f7SAndroid Build Coastguard Worker   void _shrd(Variable *Dest, Variable *Src0, Operand *Src1) {
746*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Shrd>(Dest, Src0, Src1);
747*03ce13f7SAndroid Build Coastguard Worker   }
_shufps(Variable * Dest,Operand * Src0,Operand * Src1)748*03ce13f7SAndroid Build Coastguard Worker   void _shufps(Variable *Dest, Operand *Src0, Operand *Src1) {
749*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Shufps>(Dest, Src0, Src1);
750*03ce13f7SAndroid Build Coastguard Worker   }
_movmsk(Variable * Dest,Operand * Src0)751*03ce13f7SAndroid Build Coastguard Worker   void _movmsk(Variable *Dest, Operand *Src0) {
752*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Movmsk>(Dest, Src0);
753*03ce13f7SAndroid Build Coastguard Worker   }
_sqrt(Variable * Dest,Operand * Src0)754*03ce13f7SAndroid Build Coastguard Worker   void _sqrt(Variable *Dest, Operand *Src0) {
755*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Sqrt>(Dest, Src0);
756*03ce13f7SAndroid Build Coastguard Worker   }
_store(Operand * Value,X86Operand * Mem)757*03ce13f7SAndroid Build Coastguard Worker   void _store(Operand *Value, X86Operand *Mem) {
758*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Store>(Value, Mem);
759*03ce13f7SAndroid Build Coastguard Worker   }
_storep(Variable * Value,X86OperandMem * Mem)760*03ce13f7SAndroid Build Coastguard Worker   void _storep(Variable *Value, X86OperandMem *Mem) {
761*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::StoreP>(Value, Mem);
762*03ce13f7SAndroid Build Coastguard Worker   }
_storeq(Operand * Value,X86OperandMem * Mem)763*03ce13f7SAndroid Build Coastguard Worker   void _storeq(Operand *Value, X86OperandMem *Mem) {
764*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::StoreQ>(Value, Mem);
765*03ce13f7SAndroid Build Coastguard Worker   }
_stored(Operand * Value,X86OperandMem * Mem)766*03ce13f7SAndroid Build Coastguard Worker   void _stored(Operand *Value, X86OperandMem *Mem) {
767*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::StoreD>(Value, Mem);
768*03ce13f7SAndroid Build Coastguard Worker   }
_sub(Variable * Dest,Operand * Src0)769*03ce13f7SAndroid Build Coastguard Worker   void _sub(Variable *Dest, Operand *Src0) {
770*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Sub>(Dest, Src0);
771*03ce13f7SAndroid Build Coastguard Worker   }
_sub_rmw(X86OperandMem * DestSrc0,Operand * Src1)772*03ce13f7SAndroid Build Coastguard Worker   void _sub_rmw(X86OperandMem *DestSrc0, Operand *Src1) {
773*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::SubRMW>(DestSrc0, Src1);
774*03ce13f7SAndroid Build Coastguard Worker   }
775*03ce13f7SAndroid Build Coastguard Worker   void _sub_sp(Operand *Adjustment);
_subps(Variable * Dest,Operand * Src0)776*03ce13f7SAndroid Build Coastguard Worker   void _subps(Variable *Dest, Operand *Src0) {
777*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Subps>(Dest, Src0);
778*03ce13f7SAndroid Build Coastguard Worker   }
_subss(Variable * Dest,Operand * Src0)779*03ce13f7SAndroid Build Coastguard Worker   void _subss(Variable *Dest, Operand *Src0) {
780*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Subss>(Dest, Src0);
781*03ce13f7SAndroid Build Coastguard Worker   }
_test(Operand * Src0,Operand * Src1)782*03ce13f7SAndroid Build Coastguard Worker   void _test(Operand *Src0, Operand *Src1) {
783*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Test>(Src0, Src1);
784*03ce13f7SAndroid Build Coastguard Worker   }
_ucomiss(Operand * Src0,Operand * Src1)785*03ce13f7SAndroid Build Coastguard Worker   void _ucomiss(Operand *Src0, Operand *Src1) {
786*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Ucomiss>(Src0, Src1);
787*03ce13f7SAndroid Build Coastguard Worker   }
_ud2()788*03ce13f7SAndroid Build Coastguard Worker   void _ud2() { Context.insert<Insts::UD2>(); }
789*03ce13f7SAndroid Build Coastguard Worker   void _unlink_bp();
_xadd(Operand * Dest,Variable * Src,bool Locked)790*03ce13f7SAndroid Build Coastguard Worker   void _xadd(Operand *Dest, Variable *Src, bool Locked) {
791*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Xadd>(Dest, Src, Locked);
792*03ce13f7SAndroid Build Coastguard Worker     // The xadd exchanges Dest and Src (modifying Src). Model that update with
793*03ce13f7SAndroid Build Coastguard Worker     // a FakeDef followed by a FakeUse.
794*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstFakeDef>(Src, llvm::dyn_cast<Variable>(Dest));
795*03ce13f7SAndroid Build Coastguard Worker     _set_dest_redefined();
796*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstFakeUse>(Src);
797*03ce13f7SAndroid Build Coastguard Worker   }
_xchg(Operand * Dest,Variable * Src)798*03ce13f7SAndroid Build Coastguard Worker   void _xchg(Operand *Dest, Variable *Src) {
799*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Xchg>(Dest, Src);
800*03ce13f7SAndroid Build Coastguard Worker     // The xchg modifies Dest and Src -- model that update with a
801*03ce13f7SAndroid Build Coastguard Worker     // FakeDef/FakeUse.
802*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstFakeDef>(Src, llvm::dyn_cast<Variable>(Dest));
803*03ce13f7SAndroid Build Coastguard Worker     _set_dest_redefined();
804*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstFakeUse>(Src);
805*03ce13f7SAndroid Build Coastguard Worker   }
_xor(Variable * Dest,Operand * Src0)806*03ce13f7SAndroid Build Coastguard Worker   void _xor(Variable *Dest, Operand *Src0) {
807*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Xor>(Dest, Src0);
808*03ce13f7SAndroid Build Coastguard Worker   }
_xorps(Variable * Dest,Operand * Src0)809*03ce13f7SAndroid Build Coastguard Worker   void _xorps(Variable *Dest, Operand *Src0) {
810*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::Xorps>(Dest, Src0);
811*03ce13f7SAndroid Build Coastguard Worker   }
_xor_rmw(X86OperandMem * DestSrc0,Operand * Src1)812*03ce13f7SAndroid Build Coastguard Worker   void _xor_rmw(X86OperandMem *DestSrc0, Operand *Src1) {
813*03ce13f7SAndroid Build Coastguard Worker     Context.insert<Insts::XorRMW>(DestSrc0, Src1);
814*03ce13f7SAndroid Build Coastguard Worker   }
815*03ce13f7SAndroid Build Coastguard Worker 
_iaca_start()816*03ce13f7SAndroid Build Coastguard Worker   void _iaca_start() {
817*03ce13f7SAndroid Build Coastguard Worker     if (!BuildDefs::minimal())
818*03ce13f7SAndroid Build Coastguard Worker       Context.insert<Insts::IacaStart>();
819*03ce13f7SAndroid Build Coastguard Worker   }
_iaca_end()820*03ce13f7SAndroid Build Coastguard Worker   void _iaca_end() {
821*03ce13f7SAndroid Build Coastguard Worker     if (!BuildDefs::minimal())
822*03ce13f7SAndroid Build Coastguard Worker       Context.insert<Insts::IacaEnd>();
823*03ce13f7SAndroid Build Coastguard Worker   }
824*03ce13f7SAndroid Build Coastguard Worker 
825*03ce13f7SAndroid Build Coastguard Worker   /// This class helps wrap IACA markers around the code generated by the
826*03ce13f7SAndroid Build Coastguard Worker   /// current scope. It means you don't need to put an end before each return.
827*03ce13f7SAndroid Build Coastguard Worker   class ScopedIacaMark {
828*03ce13f7SAndroid Build Coastguard Worker     ScopedIacaMark(const ScopedIacaMark &) = delete;
829*03ce13f7SAndroid Build Coastguard Worker     ScopedIacaMark &operator=(const ScopedIacaMark &) = delete;
830*03ce13f7SAndroid Build Coastguard Worker 
831*03ce13f7SAndroid Build Coastguard Worker   public:
ScopedIacaMark(TargetX8664 * Lowering)832*03ce13f7SAndroid Build Coastguard Worker     ScopedIacaMark(TargetX8664 *Lowering) : Lowering(Lowering) {
833*03ce13f7SAndroid Build Coastguard Worker       Lowering->_iaca_start();
834*03ce13f7SAndroid Build Coastguard Worker     }
~ScopedIacaMark()835*03ce13f7SAndroid Build Coastguard Worker     ~ScopedIacaMark() { end(); }
end()836*03ce13f7SAndroid Build Coastguard Worker     void end() {
837*03ce13f7SAndroid Build Coastguard Worker       if (!Lowering)
838*03ce13f7SAndroid Build Coastguard Worker         return;
839*03ce13f7SAndroid Build Coastguard Worker       Lowering->_iaca_end();
840*03ce13f7SAndroid Build Coastguard Worker       Lowering = nullptr;
841*03ce13f7SAndroid Build Coastguard Worker     }
842*03ce13f7SAndroid Build Coastguard Worker 
843*03ce13f7SAndroid Build Coastguard Worker   private:
844*03ce13f7SAndroid Build Coastguard Worker     TargetX8664 *Lowering;
845*03ce13f7SAndroid Build Coastguard Worker   };
846*03ce13f7SAndroid Build Coastguard Worker 
847*03ce13f7SAndroid Build Coastguard Worker   bool optimizeScalarMul(Variable *Dest, Operand *Src0, int32_t Src1);
848*03ce13f7SAndroid Build Coastguard Worker   void findRMW();
849*03ce13f7SAndroid Build Coastguard Worker 
850*03ce13f7SAndroid Build Coastguard Worker   static uint32_t applyStackAlignment(uint32_t Value);
851*03ce13f7SAndroid Build Coastguard Worker 
852*03ce13f7SAndroid Build Coastguard Worker   bool IsEbpBasedFrame = false;
853*03ce13f7SAndroid Build Coastguard Worker 
854*03ce13f7SAndroid Build Coastguard Worker   /// Stack alignment guaranteed by the ABI.
855*03ce13f7SAndroid Build Coastguard Worker   static constexpr uint32_t X86_STACK_ALIGNMENT_BYTES = 16;
856*03ce13f7SAndroid Build Coastguard Worker   /// Stack alignment required by the currently lowered function.
857*03ce13f7SAndroid Build Coastguard Worker   const uint32_t RequiredStackAlignment = X86_STACK_ALIGNMENT_BYTES;
858*03ce13f7SAndroid Build Coastguard Worker   size_t SpillAreaSizeBytes = 0;
859*03ce13f7SAndroid Build Coastguard Worker   size_t FixedAllocaSizeBytes = 0;
860*03ce13f7SAndroid Build Coastguard Worker   size_t FixedAllocaAlignBytes = 0;
861*03ce13f7SAndroid Build Coastguard Worker   bool PrologEmitsFixedAllocas = false;
862*03ce13f7SAndroid Build Coastguard Worker   uint32_t MaxOutArgsSizeBytes = 0;
863*03ce13f7SAndroid Build Coastguard Worker   static std::array<SmallBitVector, RCX86_NUM> TypeToRegisterSet;
864*03ce13f7SAndroid Build Coastguard Worker   static std::array<SmallBitVector, RCX86_NUM> TypeToRegisterSetUnfiltered;
865*03ce13f7SAndroid Build Coastguard Worker   static std::array<SmallBitVector, RegisterSet::Reg_NUM> RegisterAliases;
866*03ce13f7SAndroid Build Coastguard Worker   SmallBitVector RegsUsed;
867*03ce13f7SAndroid Build Coastguard Worker   std::array<VarList, IceType_NUM> PhysicalRegisters;
868*03ce13f7SAndroid Build Coastguard Worker 
869*03ce13f7SAndroid Build Coastguard Worker private:
870*03ce13f7SAndroid Build Coastguard Worker   void lowerShift64(InstArithmetic::OpKind Op, Operand *Src0Lo, Operand *Src0Hi,
871*03ce13f7SAndroid Build Coastguard Worker                     Operand *Src1Lo, Variable *DestLo, Variable *DestHi);
872*03ce13f7SAndroid Build Coastguard Worker 
873*03ce13f7SAndroid Build Coastguard Worker   /// Emit the code for a combined operation and consumer instruction, or set
874*03ce13f7SAndroid Build Coastguard Worker   /// the destination variable of the operation if Consumer == nullptr.
875*03ce13f7SAndroid Build Coastguard Worker   void lowerIcmpAndConsumer(const InstIcmp *Icmp, const Inst *Consumer);
876*03ce13f7SAndroid Build Coastguard Worker   void lowerFcmpAndConsumer(const InstFcmp *Fcmp, const Inst *Consumer);
877*03ce13f7SAndroid Build Coastguard Worker   void lowerArithAndConsumer(const InstArithmetic *Arith, const Inst *Consumer);
878*03ce13f7SAndroid Build Coastguard Worker 
879*03ce13f7SAndroid Build Coastguard Worker   /// Emit a setcc instruction if Consumer == nullptr; otherwise emit a
880*03ce13f7SAndroid Build Coastguard Worker   /// specialized version of Consumer.
881*03ce13f7SAndroid Build Coastguard Worker   void setccOrConsumer(BrCond Condition, Variable *Dest, const Inst *Consumer);
882*03ce13f7SAndroid Build Coastguard Worker 
883*03ce13f7SAndroid Build Coastguard Worker   /// Emit a mov [1|0] instruction if Consumer == nullptr; otherwise emit a
884*03ce13f7SAndroid Build Coastguard Worker   /// specialized version of Consumer.
885*03ce13f7SAndroid Build Coastguard Worker   void movOrConsumer(bool IcmpResult, Variable *Dest, const Inst *Consumer);
886*03ce13f7SAndroid Build Coastguard Worker 
887*03ce13f7SAndroid Build Coastguard Worker   /// Emit the code for instructions with a vector type.
888*03ce13f7SAndroid Build Coastguard Worker   void lowerIcmpVector(const InstIcmp *Icmp);
889*03ce13f7SAndroid Build Coastguard Worker   void lowerFcmpVector(const InstFcmp *Icmp);
890*03ce13f7SAndroid Build Coastguard Worker   void lowerSelectVector(const InstSelect *Instr);
891*03ce13f7SAndroid Build Coastguard Worker 
892*03ce13f7SAndroid Build Coastguard Worker   /// Helpers for select lowering.
893*03ce13f7SAndroid Build Coastguard Worker   void lowerSelectMove(Variable *Dest, BrCond Cond, Operand *SrcT,
894*03ce13f7SAndroid Build Coastguard Worker                        Operand *SrcF);
895*03ce13f7SAndroid Build Coastguard Worker   void lowerSelectIntMove(Variable *Dest, BrCond Cond, Operand *SrcT,
896*03ce13f7SAndroid Build Coastguard Worker                           Operand *SrcF);
897*03ce13f7SAndroid Build Coastguard Worker   /// Generic helper to move an arbitrary type from Src to Dest.
898*03ce13f7SAndroid Build Coastguard Worker   void lowerMove(Variable *Dest, Operand *Src, bool IsRedefinition);
899*03ce13f7SAndroid Build Coastguard Worker 
900*03ce13f7SAndroid Build Coastguard Worker   /// Optimizations for idiom recognition.
901*03ce13f7SAndroid Build Coastguard Worker   bool lowerOptimizeFcmpSelect(const InstFcmp *Fcmp, const InstSelect *Select);
902*03ce13f7SAndroid Build Coastguard Worker 
903*03ce13f7SAndroid Build Coastguard Worker   BoolFolding FoldingInfo;
904*03ce13f7SAndroid Build Coastguard Worker 
905*03ce13f7SAndroid Build Coastguard Worker   /// Helpers for lowering ShuffleVector
906*03ce13f7SAndroid Build Coastguard Worker   /// @{
907*03ce13f7SAndroid Build Coastguard Worker   Variable *lowerShuffleVector_AllFromSameSrc(Operand *Src, SizeT Index0,
908*03ce13f7SAndroid Build Coastguard Worker                                               SizeT Index1, SizeT Index2,
909*03ce13f7SAndroid Build Coastguard Worker                                               SizeT Index3);
910*03ce13f7SAndroid Build Coastguard Worker   static constexpr SizeT IGNORE_INDEX = 0x80000000u;
911*03ce13f7SAndroid Build Coastguard Worker   Variable *lowerShuffleVector_TwoFromSameSrc(Operand *Src0, SizeT Index0,
912*03ce13f7SAndroid Build Coastguard Worker                                               SizeT Index1, Operand *Src1,
913*03ce13f7SAndroid Build Coastguard Worker                                               SizeT Index2, SizeT Index3);
914*03ce13f7SAndroid Build Coastguard Worker   static constexpr SizeT UNIFIED_INDEX_0 = 0;
915*03ce13f7SAndroid Build Coastguard Worker   static constexpr SizeT UNIFIED_INDEX_1 = 2;
916*03ce13f7SAndroid Build Coastguard Worker   Variable *lowerShuffleVector_UnifyFromDifferentSrcs(Operand *Src0,
917*03ce13f7SAndroid Build Coastguard Worker                                                       SizeT Index0,
918*03ce13f7SAndroid Build Coastguard Worker                                                       Operand *Src1,
919*03ce13f7SAndroid Build Coastguard Worker                                                       SizeT Index1);
920*03ce13f7SAndroid Build Coastguard Worker   static constexpr SizeT CLEAR_ALL_BITS = 0x80;
921*03ce13f7SAndroid Build Coastguard Worker   SizeT PshufbMaskCount = 0;
922*03ce13f7SAndroid Build Coastguard Worker   GlobalString lowerShuffleVector_NewMaskName();
923*03ce13f7SAndroid Build Coastguard Worker   ConstantRelocatable *lowerShuffleVector_CreatePshufbMask(
924*03ce13f7SAndroid Build Coastguard Worker       int8_t Idx0, int8_t Idx1, int8_t Idx2, int8_t Idx3, int8_t Idx4,
925*03ce13f7SAndroid Build Coastguard Worker       int8_t Idx5, int8_t Idx6, int8_t Idx7, int8_t Idx8, int8_t Idx9,
926*03ce13f7SAndroid Build Coastguard Worker       int8_t Idx10, int8_t Idx11, int8_t Idx12, int8_t Idx13, int8_t Idx14,
927*03ce13f7SAndroid Build Coastguard Worker       int8_t Idx15);
928*03ce13f7SAndroid Build Coastguard Worker   void lowerShuffleVector_UsingPshufb(Variable *Dest, Operand *Src0,
929*03ce13f7SAndroid Build Coastguard Worker                                       Operand *Src1, int8_t Idx0, int8_t Idx1,
930*03ce13f7SAndroid Build Coastguard Worker                                       int8_t Idx2, int8_t Idx3, int8_t Idx4,
931*03ce13f7SAndroid Build Coastguard Worker                                       int8_t Idx5, int8_t Idx6, int8_t Idx7,
932*03ce13f7SAndroid Build Coastguard Worker                                       int8_t Idx8, int8_t Idx9, int8_t Idx10,
933*03ce13f7SAndroid Build Coastguard Worker                                       int8_t Idx11, int8_t Idx12, int8_t Idx13,
934*03ce13f7SAndroid Build Coastguard Worker                                       int8_t Idx14, int8_t Idx15);
935*03ce13f7SAndroid Build Coastguard Worker   /// @}
936*03ce13f7SAndroid Build Coastguard Worker 
937*03ce13f7SAndroid Build Coastguard Worker   /// The following table summarizes the logic for lowering the fcmp
938*03ce13f7SAndroid Build Coastguard Worker   /// instruction. There is one table entry for each of the 16 conditions.
939*03ce13f7SAndroid Build Coastguard Worker   ///
940*03ce13f7SAndroid Build Coastguard Worker   /// The first four columns describe the case when the operands are floating
941*03ce13f7SAndroid Build Coastguard Worker   /// point scalar values. A comment in lowerFcmp() describes the lowering
942*03ce13f7SAndroid Build Coastguard Worker   /// template. In the most general case, there is a compare followed by two
943*03ce13f7SAndroid Build Coastguard Worker   /// conditional branches, because some fcmp conditions don't map to a single
944*03ce13f7SAndroid Build Coastguard Worker   /// x86 conditional branch. However, in many cases it is possible to swap the
945*03ce13f7SAndroid Build Coastguard Worker   /// operands in the comparison and have a single conditional branch. Since
946*03ce13f7SAndroid Build Coastguard Worker   /// it's quite tedious to validate the table by hand, good execution tests are
947*03ce13f7SAndroid Build Coastguard Worker   /// helpful.
948*03ce13f7SAndroid Build Coastguard Worker   ///
949*03ce13f7SAndroid Build Coastguard Worker   /// The last two columns describe the case when the operands are vectors of
950*03ce13f7SAndroid Build Coastguard Worker   /// floating point values. For most fcmp conditions, there is a clear mapping
951*03ce13f7SAndroid Build Coastguard Worker   /// to a single x86 cmpps instruction variant. Some fcmp conditions require
952*03ce13f7SAndroid Build Coastguard Worker   /// special code to handle and these are marked in the table with a
953*03ce13f7SAndroid Build Coastguard Worker   /// Cmpps_Invalid predicate.
954*03ce13f7SAndroid Build Coastguard Worker   /// {@
955*03ce13f7SAndroid Build Coastguard Worker   static const struct TableFcmpType {
956*03ce13f7SAndroid Build Coastguard Worker     uint32_t Default;
957*03ce13f7SAndroid Build Coastguard Worker     bool SwapScalarOperands;
958*03ce13f7SAndroid Build Coastguard Worker     CondX86::BrCond C1, C2;
959*03ce13f7SAndroid Build Coastguard Worker     bool SwapVectorOperands;
960*03ce13f7SAndroid Build Coastguard Worker     CondX86::CmppsCond Predicate;
961*03ce13f7SAndroid Build Coastguard Worker   } TableFcmp[];
962*03ce13f7SAndroid Build Coastguard Worker   static const size_t TableFcmpSize;
963*03ce13f7SAndroid Build Coastguard Worker   /// @}
964*03ce13f7SAndroid Build Coastguard Worker 
965*03ce13f7SAndroid Build Coastguard Worker   /// The following table summarizes the logic for lowering the icmp instruction
966*03ce13f7SAndroid Build Coastguard Worker   /// for i32 and narrower types. Each icmp condition has a clear mapping to an
967*03ce13f7SAndroid Build Coastguard Worker   /// x86 conditional branch instruction.
968*03ce13f7SAndroid Build Coastguard Worker   /// {@
969*03ce13f7SAndroid Build Coastguard Worker   static const struct TableIcmp32Type {
970*03ce13f7SAndroid Build Coastguard Worker     CondX86::BrCond Mapping;
971*03ce13f7SAndroid Build Coastguard Worker   } TableIcmp32[];
972*03ce13f7SAndroid Build Coastguard Worker   static const size_t TableIcmp32Size;
973*03ce13f7SAndroid Build Coastguard Worker   /// @}
974*03ce13f7SAndroid Build Coastguard Worker 
975*03ce13f7SAndroid Build Coastguard Worker   /// The following table summarizes the logic for lowering the icmp instruction
976*03ce13f7SAndroid Build Coastguard Worker   /// for the i64 type. For Eq and Ne, two separate 32-bit comparisons and
977*03ce13f7SAndroid Build Coastguard Worker   /// conditional branches are needed. For the other conditions, three separate
978*03ce13f7SAndroid Build Coastguard Worker   /// conditional branches are needed.
979*03ce13f7SAndroid Build Coastguard Worker   /// {@
980*03ce13f7SAndroid Build Coastguard Worker   static const struct TableIcmp64Type {
981*03ce13f7SAndroid Build Coastguard Worker     CondX86::BrCond C1, C2, C3;
982*03ce13f7SAndroid Build Coastguard Worker   } TableIcmp64[];
983*03ce13f7SAndroid Build Coastguard Worker   static const size_t TableIcmp64Size;
984*03ce13f7SAndroid Build Coastguard Worker   /// @}
985*03ce13f7SAndroid Build Coastguard Worker 
getIcmp32Mapping(InstIcmp::ICond Cond)986*03ce13f7SAndroid Build Coastguard Worker   static CondX86::BrCond getIcmp32Mapping(InstIcmp::ICond Cond) {
987*03ce13f7SAndroid Build Coastguard Worker     assert(Cond < TableIcmp32Size);
988*03ce13f7SAndroid Build Coastguard Worker     return TableIcmp32[Cond].Mapping;
989*03ce13f7SAndroid Build Coastguard Worker   }
990*03ce13f7SAndroid Build Coastguard Worker 
991*03ce13f7SAndroid Build Coastguard Worker public:
create(Cfg * Func)992*03ce13f7SAndroid Build Coastguard Worker   static std::unique_ptr<::Ice::TargetLowering> create(Cfg *Func) {
993*03ce13f7SAndroid Build Coastguard Worker     return makeUnique<TargetX8664>(Func);
994*03ce13f7SAndroid Build Coastguard Worker   }
995*03ce13f7SAndroid Build Coastguard Worker 
createAssembler()996*03ce13f7SAndroid Build Coastguard Worker   std::unique_ptr<::Ice::Assembler> createAssembler() const override {
997*03ce13f7SAndroid Build Coastguard Worker     return makeUnique<X8664::AssemblerX8664>();
998*03ce13f7SAndroid Build Coastguard Worker   }
999*03ce13f7SAndroid Build Coastguard Worker 
1000*03ce13f7SAndroid Build Coastguard Worker private:
1001*03ce13f7SAndroid Build Coastguard Worker   ENABLE_MAKE_UNIQUE;
1002*03ce13f7SAndroid Build Coastguard Worker 
1003*03ce13f7SAndroid Build Coastguard Worker   explicit TargetX8664(Cfg *Func);
1004*03ce13f7SAndroid Build Coastguard Worker };
1005*03ce13f7SAndroid Build Coastguard Worker 
1006*03ce13f7SAndroid Build Coastguard Worker class TargetDataX8664 final : public TargetDataLowering {
1007*03ce13f7SAndroid Build Coastguard Worker   TargetDataX8664() = delete;
1008*03ce13f7SAndroid Build Coastguard Worker   TargetDataX8664(const TargetDataX8664 &) = delete;
1009*03ce13f7SAndroid Build Coastguard Worker   TargetDataX8664 &operator=(const TargetDataX8664 &) = delete;
1010*03ce13f7SAndroid Build Coastguard Worker 
1011*03ce13f7SAndroid Build Coastguard Worker public:
1012*03ce13f7SAndroid Build Coastguard Worker   ~TargetDataX8664() override = default;
1013*03ce13f7SAndroid Build Coastguard Worker 
create(GlobalContext * Ctx)1014*03ce13f7SAndroid Build Coastguard Worker   static std::unique_ptr<TargetDataLowering> create(GlobalContext *Ctx) {
1015*03ce13f7SAndroid Build Coastguard Worker     return makeUnique<TargetDataX8664>(Ctx);
1016*03ce13f7SAndroid Build Coastguard Worker   }
1017*03ce13f7SAndroid Build Coastguard Worker 
1018*03ce13f7SAndroid Build Coastguard Worker   void lowerGlobals(const VariableDeclarationList &Vars,
1019*03ce13f7SAndroid Build Coastguard Worker                     const std::string &SectionSuffix) override;
1020*03ce13f7SAndroid Build Coastguard Worker   void lowerConstants() override;
1021*03ce13f7SAndroid Build Coastguard Worker   void lowerJumpTables() override;
1022*03ce13f7SAndroid Build Coastguard Worker 
1023*03ce13f7SAndroid Build Coastguard Worker private:
1024*03ce13f7SAndroid Build Coastguard Worker   ENABLE_MAKE_UNIQUE;
1025*03ce13f7SAndroid Build Coastguard Worker 
TargetDataX8664(GlobalContext * Ctx)1026*03ce13f7SAndroid Build Coastguard Worker   explicit TargetDataX8664(GlobalContext *Ctx) : TargetDataLowering(Ctx) {}
1027*03ce13f7SAndroid Build Coastguard Worker   template <typename T> static void emitConstantPool(GlobalContext *Ctx);
1028*03ce13f7SAndroid Build Coastguard Worker };
1029*03ce13f7SAndroid Build Coastguard Worker 
1030*03ce13f7SAndroid Build Coastguard Worker class TargetHeaderX86 : public TargetHeaderLowering {
1031*03ce13f7SAndroid Build Coastguard Worker   TargetHeaderX86() = delete;
1032*03ce13f7SAndroid Build Coastguard Worker   TargetHeaderX86(const TargetHeaderX86 &) = delete;
1033*03ce13f7SAndroid Build Coastguard Worker   TargetHeaderX86 &operator=(const TargetHeaderX86 &) = delete;
1034*03ce13f7SAndroid Build Coastguard Worker 
1035*03ce13f7SAndroid Build Coastguard Worker public:
1036*03ce13f7SAndroid Build Coastguard Worker   ~TargetHeaderX86() = default;
1037*03ce13f7SAndroid Build Coastguard Worker 
create(GlobalContext * Ctx)1038*03ce13f7SAndroid Build Coastguard Worker   static std::unique_ptr<TargetHeaderLowering> create(GlobalContext *Ctx) {
1039*03ce13f7SAndroid Build Coastguard Worker     return makeUnique<TargetHeaderX86>(Ctx);
1040*03ce13f7SAndroid Build Coastguard Worker   }
1041*03ce13f7SAndroid Build Coastguard Worker 
1042*03ce13f7SAndroid Build Coastguard Worker private:
1043*03ce13f7SAndroid Build Coastguard Worker   ENABLE_MAKE_UNIQUE;
1044*03ce13f7SAndroid Build Coastguard Worker 
TargetHeaderX86(GlobalContext * Ctx)1045*03ce13f7SAndroid Build Coastguard Worker   explicit TargetHeaderX86(GlobalContext *Ctx) : TargetHeaderLowering(Ctx) {}
1046*03ce13f7SAndroid Build Coastguard Worker };
1047*03ce13f7SAndroid Build Coastguard Worker 
1048*03ce13f7SAndroid Build Coastguard Worker } // end of namespace X8664
1049*03ce13f7SAndroid Build Coastguard Worker } // end of namespace Ice
1050*03ce13f7SAndroid Build Coastguard Worker 
1051*03ce13f7SAndroid Build Coastguard Worker #endif // SUBZERO_SRC_ICETARGETLOWERINGX8664_H
1052