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