1*9880d681SAndroid Build Coastguard Worker //===-- X86FastISel.cpp - X86 FastISel implementation ---------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file defines the X86-specific support for the FastISel class. Much
11*9880d681SAndroid Build Coastguard Worker // of the target-specific code is generated by tablegen in the file
12*9880d681SAndroid Build Coastguard Worker // X86GenFastISel.inc, which is #included here.
13*9880d681SAndroid Build Coastguard Worker //
14*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
15*9880d681SAndroid Build Coastguard Worker
16*9880d681SAndroid Build Coastguard Worker #include "X86.h"
17*9880d681SAndroid Build Coastguard Worker #include "X86CallingConv.h"
18*9880d681SAndroid Build Coastguard Worker #include "X86InstrBuilder.h"
19*9880d681SAndroid Build Coastguard Worker #include "X86InstrInfo.h"
20*9880d681SAndroid Build Coastguard Worker #include "X86MachineFunctionInfo.h"
21*9880d681SAndroid Build Coastguard Worker #include "X86RegisterInfo.h"
22*9880d681SAndroid Build Coastguard Worker #include "X86Subtarget.h"
23*9880d681SAndroid Build Coastguard Worker #include "X86TargetMachine.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/BranchProbabilityInfo.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/FastISel.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/FunctionLoweringInfo.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineConstantPool.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFrameInfo.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/CallSite.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/CallingConv.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DebugInfo.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DerivedTypes.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/GetElementPtrTypeIterator.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/GlobalAlias.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/GlobalVariable.h"
37*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Instructions.h"
38*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/IntrinsicInst.h"
39*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Operator.h"
40*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmInfo.h"
41*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSymbol.h"
42*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
43*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetOptions.h"
44*9880d681SAndroid Build Coastguard Worker using namespace llvm;
45*9880d681SAndroid Build Coastguard Worker
46*9880d681SAndroid Build Coastguard Worker namespace {
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Worker class X86FastISel final : public FastISel {
49*9880d681SAndroid Build Coastguard Worker /// Subtarget - Keep a pointer to the X86Subtarget around so that we can
50*9880d681SAndroid Build Coastguard Worker /// make the right decision when generating code for different targets.
51*9880d681SAndroid Build Coastguard Worker const X86Subtarget *Subtarget;
52*9880d681SAndroid Build Coastguard Worker
53*9880d681SAndroid Build Coastguard Worker /// X86ScalarSSEf32, X86ScalarSSEf64 - Select between SSE or x87
54*9880d681SAndroid Build Coastguard Worker /// floating point ops.
55*9880d681SAndroid Build Coastguard Worker /// When SSE is available, use it for f32 operations.
56*9880d681SAndroid Build Coastguard Worker /// When SSE2 is available, use it for f64 operations.
57*9880d681SAndroid Build Coastguard Worker bool X86ScalarSSEf64;
58*9880d681SAndroid Build Coastguard Worker bool X86ScalarSSEf32;
59*9880d681SAndroid Build Coastguard Worker
60*9880d681SAndroid Build Coastguard Worker public:
X86FastISel(FunctionLoweringInfo & funcInfo,const TargetLibraryInfo * libInfo)61*9880d681SAndroid Build Coastguard Worker explicit X86FastISel(FunctionLoweringInfo &funcInfo,
62*9880d681SAndroid Build Coastguard Worker const TargetLibraryInfo *libInfo)
63*9880d681SAndroid Build Coastguard Worker : FastISel(funcInfo, libInfo) {
64*9880d681SAndroid Build Coastguard Worker Subtarget = &funcInfo.MF->getSubtarget<X86Subtarget>();
65*9880d681SAndroid Build Coastguard Worker X86ScalarSSEf64 = Subtarget->hasSSE2();
66*9880d681SAndroid Build Coastguard Worker X86ScalarSSEf32 = Subtarget->hasSSE1();
67*9880d681SAndroid Build Coastguard Worker }
68*9880d681SAndroid Build Coastguard Worker
69*9880d681SAndroid Build Coastguard Worker bool fastSelectInstruction(const Instruction *I) override;
70*9880d681SAndroid Build Coastguard Worker
71*9880d681SAndroid Build Coastguard Worker /// \brief The specified machine instr operand is a vreg, and that
72*9880d681SAndroid Build Coastguard Worker /// vreg is being provided by the specified load instruction. If possible,
73*9880d681SAndroid Build Coastguard Worker /// try to fold the load as an operand to the instruction, returning true if
74*9880d681SAndroid Build Coastguard Worker /// possible.
75*9880d681SAndroid Build Coastguard Worker bool tryToFoldLoadIntoMI(MachineInstr *MI, unsigned OpNo,
76*9880d681SAndroid Build Coastguard Worker const LoadInst *LI) override;
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard Worker bool fastLowerArguments() override;
79*9880d681SAndroid Build Coastguard Worker bool fastLowerCall(CallLoweringInfo &CLI) override;
80*9880d681SAndroid Build Coastguard Worker bool fastLowerIntrinsicCall(const IntrinsicInst *II) override;
81*9880d681SAndroid Build Coastguard Worker
82*9880d681SAndroid Build Coastguard Worker #include "X86GenFastISel.inc"
83*9880d681SAndroid Build Coastguard Worker
84*9880d681SAndroid Build Coastguard Worker private:
85*9880d681SAndroid Build Coastguard Worker bool X86FastEmitCompare(const Value *LHS, const Value *RHS, EVT VT,
86*9880d681SAndroid Build Coastguard Worker const DebugLoc &DL);
87*9880d681SAndroid Build Coastguard Worker
88*9880d681SAndroid Build Coastguard Worker bool X86FastEmitLoad(EVT VT, X86AddressMode &AM, MachineMemOperand *MMO,
89*9880d681SAndroid Build Coastguard Worker unsigned &ResultReg, unsigned Alignment = 1);
90*9880d681SAndroid Build Coastguard Worker
91*9880d681SAndroid Build Coastguard Worker bool X86FastEmitStore(EVT VT, const Value *Val, X86AddressMode &AM,
92*9880d681SAndroid Build Coastguard Worker MachineMemOperand *MMO = nullptr, bool Aligned = false);
93*9880d681SAndroid Build Coastguard Worker bool X86FastEmitStore(EVT VT, unsigned ValReg, bool ValIsKill,
94*9880d681SAndroid Build Coastguard Worker X86AddressMode &AM,
95*9880d681SAndroid Build Coastguard Worker MachineMemOperand *MMO = nullptr, bool Aligned = false);
96*9880d681SAndroid Build Coastguard Worker
97*9880d681SAndroid Build Coastguard Worker bool X86FastEmitExtend(ISD::NodeType Opc, EVT DstVT, unsigned Src, EVT SrcVT,
98*9880d681SAndroid Build Coastguard Worker unsigned &ResultReg);
99*9880d681SAndroid Build Coastguard Worker
100*9880d681SAndroid Build Coastguard Worker bool X86SelectAddress(const Value *V, X86AddressMode &AM);
101*9880d681SAndroid Build Coastguard Worker bool X86SelectCallAddress(const Value *V, X86AddressMode &AM);
102*9880d681SAndroid Build Coastguard Worker
103*9880d681SAndroid Build Coastguard Worker bool X86SelectLoad(const Instruction *I);
104*9880d681SAndroid Build Coastguard Worker
105*9880d681SAndroid Build Coastguard Worker bool X86SelectStore(const Instruction *I);
106*9880d681SAndroid Build Coastguard Worker
107*9880d681SAndroid Build Coastguard Worker bool X86SelectRet(const Instruction *I);
108*9880d681SAndroid Build Coastguard Worker
109*9880d681SAndroid Build Coastguard Worker bool X86SelectCmp(const Instruction *I);
110*9880d681SAndroid Build Coastguard Worker
111*9880d681SAndroid Build Coastguard Worker bool X86SelectZExt(const Instruction *I);
112*9880d681SAndroid Build Coastguard Worker
113*9880d681SAndroid Build Coastguard Worker bool X86SelectBranch(const Instruction *I);
114*9880d681SAndroid Build Coastguard Worker
115*9880d681SAndroid Build Coastguard Worker bool X86SelectShift(const Instruction *I);
116*9880d681SAndroid Build Coastguard Worker
117*9880d681SAndroid Build Coastguard Worker bool X86SelectDivRem(const Instruction *I);
118*9880d681SAndroid Build Coastguard Worker
119*9880d681SAndroid Build Coastguard Worker bool X86FastEmitCMoveSelect(MVT RetVT, const Instruction *I);
120*9880d681SAndroid Build Coastguard Worker
121*9880d681SAndroid Build Coastguard Worker bool X86FastEmitSSESelect(MVT RetVT, const Instruction *I);
122*9880d681SAndroid Build Coastguard Worker
123*9880d681SAndroid Build Coastguard Worker bool X86FastEmitPseudoSelect(MVT RetVT, const Instruction *I);
124*9880d681SAndroid Build Coastguard Worker
125*9880d681SAndroid Build Coastguard Worker bool X86SelectSelect(const Instruction *I);
126*9880d681SAndroid Build Coastguard Worker
127*9880d681SAndroid Build Coastguard Worker bool X86SelectTrunc(const Instruction *I);
128*9880d681SAndroid Build Coastguard Worker
129*9880d681SAndroid Build Coastguard Worker bool X86SelectFPExtOrFPTrunc(const Instruction *I, unsigned Opc,
130*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC);
131*9880d681SAndroid Build Coastguard Worker
132*9880d681SAndroid Build Coastguard Worker bool X86SelectFPExt(const Instruction *I);
133*9880d681SAndroid Build Coastguard Worker bool X86SelectFPTrunc(const Instruction *I);
134*9880d681SAndroid Build Coastguard Worker bool X86SelectSIToFP(const Instruction *I);
135*9880d681SAndroid Build Coastguard Worker
getInstrInfo() const136*9880d681SAndroid Build Coastguard Worker const X86InstrInfo *getInstrInfo() const {
137*9880d681SAndroid Build Coastguard Worker return Subtarget->getInstrInfo();
138*9880d681SAndroid Build Coastguard Worker }
getTargetMachine() const139*9880d681SAndroid Build Coastguard Worker const X86TargetMachine *getTargetMachine() const {
140*9880d681SAndroid Build Coastguard Worker return static_cast<const X86TargetMachine *>(&TM);
141*9880d681SAndroid Build Coastguard Worker }
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Worker bool handleConstantAddresses(const Value *V, X86AddressMode &AM);
144*9880d681SAndroid Build Coastguard Worker
145*9880d681SAndroid Build Coastguard Worker unsigned X86MaterializeInt(const ConstantInt *CI, MVT VT);
146*9880d681SAndroid Build Coastguard Worker unsigned X86MaterializeFP(const ConstantFP *CFP, MVT VT);
147*9880d681SAndroid Build Coastguard Worker unsigned X86MaterializeGV(const GlobalValue *GV, MVT VT);
148*9880d681SAndroid Build Coastguard Worker unsigned fastMaterializeConstant(const Constant *C) override;
149*9880d681SAndroid Build Coastguard Worker
150*9880d681SAndroid Build Coastguard Worker unsigned fastMaterializeAlloca(const AllocaInst *C) override;
151*9880d681SAndroid Build Coastguard Worker
152*9880d681SAndroid Build Coastguard Worker unsigned fastMaterializeFloatZero(const ConstantFP *CF) override;
153*9880d681SAndroid Build Coastguard Worker
154*9880d681SAndroid Build Coastguard Worker /// isScalarFPTypeInSSEReg - Return true if the specified scalar FP type is
155*9880d681SAndroid Build Coastguard Worker /// computed in an SSE register, not on the X87 floating point stack.
isScalarFPTypeInSSEReg(EVT VT) const156*9880d681SAndroid Build Coastguard Worker bool isScalarFPTypeInSSEReg(EVT VT) const {
157*9880d681SAndroid Build Coastguard Worker return (VT == MVT::f64 && X86ScalarSSEf64) || // f64 is when SSE2
158*9880d681SAndroid Build Coastguard Worker (VT == MVT::f32 && X86ScalarSSEf32); // f32 is when SSE1
159*9880d681SAndroid Build Coastguard Worker }
160*9880d681SAndroid Build Coastguard Worker
161*9880d681SAndroid Build Coastguard Worker bool isTypeLegal(Type *Ty, MVT &VT, bool AllowI1 = false);
162*9880d681SAndroid Build Coastguard Worker
163*9880d681SAndroid Build Coastguard Worker bool IsMemcpySmall(uint64_t Len);
164*9880d681SAndroid Build Coastguard Worker
165*9880d681SAndroid Build Coastguard Worker bool TryEmitSmallMemcpy(X86AddressMode DestAM,
166*9880d681SAndroid Build Coastguard Worker X86AddressMode SrcAM, uint64_t Len);
167*9880d681SAndroid Build Coastguard Worker
168*9880d681SAndroid Build Coastguard Worker bool foldX86XALUIntrinsic(X86::CondCode &CC, const Instruction *I,
169*9880d681SAndroid Build Coastguard Worker const Value *Cond);
170*9880d681SAndroid Build Coastguard Worker
171*9880d681SAndroid Build Coastguard Worker const MachineInstrBuilder &addFullAddress(const MachineInstrBuilder &MIB,
172*9880d681SAndroid Build Coastguard Worker X86AddressMode &AM);
173*9880d681SAndroid Build Coastguard Worker };
174*9880d681SAndroid Build Coastguard Worker
175*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace.
176*9880d681SAndroid Build Coastguard Worker
177*9880d681SAndroid Build Coastguard Worker static std::pair<X86::CondCode, bool>
getX86ConditionCode(CmpInst::Predicate Predicate)178*9880d681SAndroid Build Coastguard Worker getX86ConditionCode(CmpInst::Predicate Predicate) {
179*9880d681SAndroid Build Coastguard Worker X86::CondCode CC = X86::COND_INVALID;
180*9880d681SAndroid Build Coastguard Worker bool NeedSwap = false;
181*9880d681SAndroid Build Coastguard Worker switch (Predicate) {
182*9880d681SAndroid Build Coastguard Worker default: break;
183*9880d681SAndroid Build Coastguard Worker // Floating-point Predicates
184*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_UEQ: CC = X86::COND_E; break;
185*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_OLT: NeedSwap = true; // fall-through
186*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_OGT: CC = X86::COND_A; break;
187*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_OLE: NeedSwap = true; // fall-through
188*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_OGE: CC = X86::COND_AE; break;
189*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_UGT: NeedSwap = true; // fall-through
190*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_ULT: CC = X86::COND_B; break;
191*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_UGE: NeedSwap = true; // fall-through
192*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_ULE: CC = X86::COND_BE; break;
193*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_ONE: CC = X86::COND_NE; break;
194*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_UNO: CC = X86::COND_P; break;
195*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_ORD: CC = X86::COND_NP; break;
196*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_OEQ: // fall-through
197*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_UNE: CC = X86::COND_INVALID; break;
198*9880d681SAndroid Build Coastguard Worker
199*9880d681SAndroid Build Coastguard Worker // Integer Predicates
200*9880d681SAndroid Build Coastguard Worker case CmpInst::ICMP_EQ: CC = X86::COND_E; break;
201*9880d681SAndroid Build Coastguard Worker case CmpInst::ICMP_NE: CC = X86::COND_NE; break;
202*9880d681SAndroid Build Coastguard Worker case CmpInst::ICMP_UGT: CC = X86::COND_A; break;
203*9880d681SAndroid Build Coastguard Worker case CmpInst::ICMP_UGE: CC = X86::COND_AE; break;
204*9880d681SAndroid Build Coastguard Worker case CmpInst::ICMP_ULT: CC = X86::COND_B; break;
205*9880d681SAndroid Build Coastguard Worker case CmpInst::ICMP_ULE: CC = X86::COND_BE; break;
206*9880d681SAndroid Build Coastguard Worker case CmpInst::ICMP_SGT: CC = X86::COND_G; break;
207*9880d681SAndroid Build Coastguard Worker case CmpInst::ICMP_SGE: CC = X86::COND_GE; break;
208*9880d681SAndroid Build Coastguard Worker case CmpInst::ICMP_SLT: CC = X86::COND_L; break;
209*9880d681SAndroid Build Coastguard Worker case CmpInst::ICMP_SLE: CC = X86::COND_LE; break;
210*9880d681SAndroid Build Coastguard Worker }
211*9880d681SAndroid Build Coastguard Worker
212*9880d681SAndroid Build Coastguard Worker return std::make_pair(CC, NeedSwap);
213*9880d681SAndroid Build Coastguard Worker }
214*9880d681SAndroid Build Coastguard Worker
215*9880d681SAndroid Build Coastguard Worker static std::pair<unsigned, bool>
getX86SSEConditionCode(CmpInst::Predicate Predicate)216*9880d681SAndroid Build Coastguard Worker getX86SSEConditionCode(CmpInst::Predicate Predicate) {
217*9880d681SAndroid Build Coastguard Worker unsigned CC;
218*9880d681SAndroid Build Coastguard Worker bool NeedSwap = false;
219*9880d681SAndroid Build Coastguard Worker
220*9880d681SAndroid Build Coastguard Worker // SSE Condition code mapping:
221*9880d681SAndroid Build Coastguard Worker // 0 - EQ
222*9880d681SAndroid Build Coastguard Worker // 1 - LT
223*9880d681SAndroid Build Coastguard Worker // 2 - LE
224*9880d681SAndroid Build Coastguard Worker // 3 - UNORD
225*9880d681SAndroid Build Coastguard Worker // 4 - NEQ
226*9880d681SAndroid Build Coastguard Worker // 5 - NLT
227*9880d681SAndroid Build Coastguard Worker // 6 - NLE
228*9880d681SAndroid Build Coastguard Worker // 7 - ORD
229*9880d681SAndroid Build Coastguard Worker switch (Predicate) {
230*9880d681SAndroid Build Coastguard Worker default: llvm_unreachable("Unexpected predicate");
231*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_OEQ: CC = 0; break;
232*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_OGT: NeedSwap = true; // fall-through
233*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_OLT: CC = 1; break;
234*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_OGE: NeedSwap = true; // fall-through
235*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_OLE: CC = 2; break;
236*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_UNO: CC = 3; break;
237*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_UNE: CC = 4; break;
238*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_ULE: NeedSwap = true; // fall-through
239*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_UGE: CC = 5; break;
240*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_ULT: NeedSwap = true; // fall-through
241*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_UGT: CC = 6; break;
242*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_ORD: CC = 7; break;
243*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_UEQ:
244*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_ONE: CC = 8; break;
245*9880d681SAndroid Build Coastguard Worker }
246*9880d681SAndroid Build Coastguard Worker
247*9880d681SAndroid Build Coastguard Worker return std::make_pair(CC, NeedSwap);
248*9880d681SAndroid Build Coastguard Worker }
249*9880d681SAndroid Build Coastguard Worker
250*9880d681SAndroid Build Coastguard Worker /// \brief Adds a complex addressing mode to the given machine instr builder.
251*9880d681SAndroid Build Coastguard Worker /// Note, this will constrain the index register. If its not possible to
252*9880d681SAndroid Build Coastguard Worker /// constrain the given index register, then a new one will be created. The
253*9880d681SAndroid Build Coastguard Worker /// IndexReg field of the addressing mode will be updated to match in this case.
254*9880d681SAndroid Build Coastguard Worker const MachineInstrBuilder &
addFullAddress(const MachineInstrBuilder & MIB,X86AddressMode & AM)255*9880d681SAndroid Build Coastguard Worker X86FastISel::addFullAddress(const MachineInstrBuilder &MIB,
256*9880d681SAndroid Build Coastguard Worker X86AddressMode &AM) {
257*9880d681SAndroid Build Coastguard Worker // First constrain the index register. It needs to be a GR64_NOSP.
258*9880d681SAndroid Build Coastguard Worker AM.IndexReg = constrainOperandRegClass(MIB->getDesc(), AM.IndexReg,
259*9880d681SAndroid Build Coastguard Worker MIB->getNumOperands() +
260*9880d681SAndroid Build Coastguard Worker X86::AddrIndexReg);
261*9880d681SAndroid Build Coastguard Worker return ::addFullAddress(MIB, AM);
262*9880d681SAndroid Build Coastguard Worker }
263*9880d681SAndroid Build Coastguard Worker
264*9880d681SAndroid Build Coastguard Worker /// \brief Check if it is possible to fold the condition from the XALU intrinsic
265*9880d681SAndroid Build Coastguard Worker /// into the user. The condition code will only be updated on success.
foldX86XALUIntrinsic(X86::CondCode & CC,const Instruction * I,const Value * Cond)266*9880d681SAndroid Build Coastguard Worker bool X86FastISel::foldX86XALUIntrinsic(X86::CondCode &CC, const Instruction *I,
267*9880d681SAndroid Build Coastguard Worker const Value *Cond) {
268*9880d681SAndroid Build Coastguard Worker if (!isa<ExtractValueInst>(Cond))
269*9880d681SAndroid Build Coastguard Worker return false;
270*9880d681SAndroid Build Coastguard Worker
271*9880d681SAndroid Build Coastguard Worker const auto *EV = cast<ExtractValueInst>(Cond);
272*9880d681SAndroid Build Coastguard Worker if (!isa<IntrinsicInst>(EV->getAggregateOperand()))
273*9880d681SAndroid Build Coastguard Worker return false;
274*9880d681SAndroid Build Coastguard Worker
275*9880d681SAndroid Build Coastguard Worker const auto *II = cast<IntrinsicInst>(EV->getAggregateOperand());
276*9880d681SAndroid Build Coastguard Worker MVT RetVT;
277*9880d681SAndroid Build Coastguard Worker const Function *Callee = II->getCalledFunction();
278*9880d681SAndroid Build Coastguard Worker Type *RetTy =
279*9880d681SAndroid Build Coastguard Worker cast<StructType>(Callee->getReturnType())->getTypeAtIndex(0U);
280*9880d681SAndroid Build Coastguard Worker if (!isTypeLegal(RetTy, RetVT))
281*9880d681SAndroid Build Coastguard Worker return false;
282*9880d681SAndroid Build Coastguard Worker
283*9880d681SAndroid Build Coastguard Worker if (RetVT != MVT::i32 && RetVT != MVT::i64)
284*9880d681SAndroid Build Coastguard Worker return false;
285*9880d681SAndroid Build Coastguard Worker
286*9880d681SAndroid Build Coastguard Worker X86::CondCode TmpCC;
287*9880d681SAndroid Build Coastguard Worker switch (II->getIntrinsicID()) {
288*9880d681SAndroid Build Coastguard Worker default: return false;
289*9880d681SAndroid Build Coastguard Worker case Intrinsic::sadd_with_overflow:
290*9880d681SAndroid Build Coastguard Worker case Intrinsic::ssub_with_overflow:
291*9880d681SAndroid Build Coastguard Worker case Intrinsic::smul_with_overflow:
292*9880d681SAndroid Build Coastguard Worker case Intrinsic::umul_with_overflow: TmpCC = X86::COND_O; break;
293*9880d681SAndroid Build Coastguard Worker case Intrinsic::uadd_with_overflow:
294*9880d681SAndroid Build Coastguard Worker case Intrinsic::usub_with_overflow: TmpCC = X86::COND_B; break;
295*9880d681SAndroid Build Coastguard Worker }
296*9880d681SAndroid Build Coastguard Worker
297*9880d681SAndroid Build Coastguard Worker // Check if both instructions are in the same basic block.
298*9880d681SAndroid Build Coastguard Worker if (II->getParent() != I->getParent())
299*9880d681SAndroid Build Coastguard Worker return false;
300*9880d681SAndroid Build Coastguard Worker
301*9880d681SAndroid Build Coastguard Worker // Make sure nothing is in the way
302*9880d681SAndroid Build Coastguard Worker BasicBlock::const_iterator Start(I);
303*9880d681SAndroid Build Coastguard Worker BasicBlock::const_iterator End(II);
304*9880d681SAndroid Build Coastguard Worker for (auto Itr = std::prev(Start); Itr != End; --Itr) {
305*9880d681SAndroid Build Coastguard Worker // We only expect extractvalue instructions between the intrinsic and the
306*9880d681SAndroid Build Coastguard Worker // instruction to be selected.
307*9880d681SAndroid Build Coastguard Worker if (!isa<ExtractValueInst>(Itr))
308*9880d681SAndroid Build Coastguard Worker return false;
309*9880d681SAndroid Build Coastguard Worker
310*9880d681SAndroid Build Coastguard Worker // Check that the extractvalue operand comes from the intrinsic.
311*9880d681SAndroid Build Coastguard Worker const auto *EVI = cast<ExtractValueInst>(Itr);
312*9880d681SAndroid Build Coastguard Worker if (EVI->getAggregateOperand() != II)
313*9880d681SAndroid Build Coastguard Worker return false;
314*9880d681SAndroid Build Coastguard Worker }
315*9880d681SAndroid Build Coastguard Worker
316*9880d681SAndroid Build Coastguard Worker CC = TmpCC;
317*9880d681SAndroid Build Coastguard Worker return true;
318*9880d681SAndroid Build Coastguard Worker }
319*9880d681SAndroid Build Coastguard Worker
isTypeLegal(Type * Ty,MVT & VT,bool AllowI1)320*9880d681SAndroid Build Coastguard Worker bool X86FastISel::isTypeLegal(Type *Ty, MVT &VT, bool AllowI1) {
321*9880d681SAndroid Build Coastguard Worker EVT evt = TLI.getValueType(DL, Ty, /*HandleUnknown=*/true);
322*9880d681SAndroid Build Coastguard Worker if (evt == MVT::Other || !evt.isSimple())
323*9880d681SAndroid Build Coastguard Worker // Unhandled type. Halt "fast" selection and bail.
324*9880d681SAndroid Build Coastguard Worker return false;
325*9880d681SAndroid Build Coastguard Worker
326*9880d681SAndroid Build Coastguard Worker VT = evt.getSimpleVT();
327*9880d681SAndroid Build Coastguard Worker // For now, require SSE/SSE2 for performing floating-point operations,
328*9880d681SAndroid Build Coastguard Worker // since x87 requires additional work.
329*9880d681SAndroid Build Coastguard Worker if (VT == MVT::f64 && !X86ScalarSSEf64)
330*9880d681SAndroid Build Coastguard Worker return false;
331*9880d681SAndroid Build Coastguard Worker if (VT == MVT::f32 && !X86ScalarSSEf32)
332*9880d681SAndroid Build Coastguard Worker return false;
333*9880d681SAndroid Build Coastguard Worker // Similarly, no f80 support yet.
334*9880d681SAndroid Build Coastguard Worker if (VT == MVT::f80)
335*9880d681SAndroid Build Coastguard Worker return false;
336*9880d681SAndroid Build Coastguard Worker // We only handle legal types. For example, on x86-32 the instruction
337*9880d681SAndroid Build Coastguard Worker // selector contains all of the 64-bit instructions from x86-64,
338*9880d681SAndroid Build Coastguard Worker // under the assumption that i64 won't be used if the target doesn't
339*9880d681SAndroid Build Coastguard Worker // support it.
340*9880d681SAndroid Build Coastguard Worker return (AllowI1 && VT == MVT::i1) || TLI.isTypeLegal(VT);
341*9880d681SAndroid Build Coastguard Worker }
342*9880d681SAndroid Build Coastguard Worker
343*9880d681SAndroid Build Coastguard Worker #include "X86GenCallingConv.inc"
344*9880d681SAndroid Build Coastguard Worker
345*9880d681SAndroid Build Coastguard Worker /// X86FastEmitLoad - Emit a machine instruction to load a value of type VT.
346*9880d681SAndroid Build Coastguard Worker /// The address is either pre-computed, i.e. Ptr, or a GlobalAddress, i.e. GV.
347*9880d681SAndroid Build Coastguard Worker /// Return true and the result register by reference if it is possible.
X86FastEmitLoad(EVT VT,X86AddressMode & AM,MachineMemOperand * MMO,unsigned & ResultReg,unsigned Alignment)348*9880d681SAndroid Build Coastguard Worker bool X86FastISel::X86FastEmitLoad(EVT VT, X86AddressMode &AM,
349*9880d681SAndroid Build Coastguard Worker MachineMemOperand *MMO, unsigned &ResultReg,
350*9880d681SAndroid Build Coastguard Worker unsigned Alignment) {
351*9880d681SAndroid Build Coastguard Worker bool HasSSE41 = Subtarget->hasSSE41();
352*9880d681SAndroid Build Coastguard Worker bool HasAVX = Subtarget->hasAVX();
353*9880d681SAndroid Build Coastguard Worker bool HasAVX2 = Subtarget->hasAVX2();
354*9880d681SAndroid Build Coastguard Worker bool IsNonTemporal = MMO && MMO->isNonTemporal();
355*9880d681SAndroid Build Coastguard Worker
356*9880d681SAndroid Build Coastguard Worker // Get opcode and regclass of the output for the given load instruction.
357*9880d681SAndroid Build Coastguard Worker unsigned Opc = 0;
358*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = nullptr;
359*9880d681SAndroid Build Coastguard Worker switch (VT.getSimpleVT().SimpleTy) {
360*9880d681SAndroid Build Coastguard Worker default: return false;
361*9880d681SAndroid Build Coastguard Worker case MVT::i1:
362*9880d681SAndroid Build Coastguard Worker case MVT::i8:
363*9880d681SAndroid Build Coastguard Worker Opc = X86::MOV8rm;
364*9880d681SAndroid Build Coastguard Worker RC = &X86::GR8RegClass;
365*9880d681SAndroid Build Coastguard Worker break;
366*9880d681SAndroid Build Coastguard Worker case MVT::i16:
367*9880d681SAndroid Build Coastguard Worker Opc = X86::MOV16rm;
368*9880d681SAndroid Build Coastguard Worker RC = &X86::GR16RegClass;
369*9880d681SAndroid Build Coastguard Worker break;
370*9880d681SAndroid Build Coastguard Worker case MVT::i32:
371*9880d681SAndroid Build Coastguard Worker Opc = X86::MOV32rm;
372*9880d681SAndroid Build Coastguard Worker RC = &X86::GR32RegClass;
373*9880d681SAndroid Build Coastguard Worker break;
374*9880d681SAndroid Build Coastguard Worker case MVT::i64:
375*9880d681SAndroid Build Coastguard Worker // Must be in x86-64 mode.
376*9880d681SAndroid Build Coastguard Worker Opc = X86::MOV64rm;
377*9880d681SAndroid Build Coastguard Worker RC = &X86::GR64RegClass;
378*9880d681SAndroid Build Coastguard Worker break;
379*9880d681SAndroid Build Coastguard Worker case MVT::f32:
380*9880d681SAndroid Build Coastguard Worker if (X86ScalarSSEf32) {
381*9880d681SAndroid Build Coastguard Worker Opc = HasAVX ? X86::VMOVSSrm : X86::MOVSSrm;
382*9880d681SAndroid Build Coastguard Worker RC = &X86::FR32RegClass;
383*9880d681SAndroid Build Coastguard Worker } else {
384*9880d681SAndroid Build Coastguard Worker Opc = X86::LD_Fp32m;
385*9880d681SAndroid Build Coastguard Worker RC = &X86::RFP32RegClass;
386*9880d681SAndroid Build Coastguard Worker }
387*9880d681SAndroid Build Coastguard Worker break;
388*9880d681SAndroid Build Coastguard Worker case MVT::f64:
389*9880d681SAndroid Build Coastguard Worker if (X86ScalarSSEf64) {
390*9880d681SAndroid Build Coastguard Worker Opc = HasAVX ? X86::VMOVSDrm : X86::MOVSDrm;
391*9880d681SAndroid Build Coastguard Worker RC = &X86::FR64RegClass;
392*9880d681SAndroid Build Coastguard Worker } else {
393*9880d681SAndroid Build Coastguard Worker Opc = X86::LD_Fp64m;
394*9880d681SAndroid Build Coastguard Worker RC = &X86::RFP64RegClass;
395*9880d681SAndroid Build Coastguard Worker }
396*9880d681SAndroid Build Coastguard Worker break;
397*9880d681SAndroid Build Coastguard Worker case MVT::f80:
398*9880d681SAndroid Build Coastguard Worker // No f80 support yet.
399*9880d681SAndroid Build Coastguard Worker return false;
400*9880d681SAndroid Build Coastguard Worker case MVT::v4f32:
401*9880d681SAndroid Build Coastguard Worker if (IsNonTemporal && Alignment >= 16 && HasSSE41)
402*9880d681SAndroid Build Coastguard Worker Opc = HasAVX ? X86::VMOVNTDQArm : X86::MOVNTDQArm;
403*9880d681SAndroid Build Coastguard Worker else if (Alignment >= 16)
404*9880d681SAndroid Build Coastguard Worker Opc = HasAVX ? X86::VMOVAPSrm : X86::MOVAPSrm;
405*9880d681SAndroid Build Coastguard Worker else
406*9880d681SAndroid Build Coastguard Worker Opc = HasAVX ? X86::VMOVUPSrm : X86::MOVUPSrm;
407*9880d681SAndroid Build Coastguard Worker RC = &X86::VR128RegClass;
408*9880d681SAndroid Build Coastguard Worker break;
409*9880d681SAndroid Build Coastguard Worker case MVT::v2f64:
410*9880d681SAndroid Build Coastguard Worker if (IsNonTemporal && Alignment >= 16 && HasSSE41)
411*9880d681SAndroid Build Coastguard Worker Opc = HasAVX ? X86::VMOVNTDQArm : X86::MOVNTDQArm;
412*9880d681SAndroid Build Coastguard Worker else if (Alignment >= 16)
413*9880d681SAndroid Build Coastguard Worker Opc = HasAVX ? X86::VMOVAPDrm : X86::MOVAPDrm;
414*9880d681SAndroid Build Coastguard Worker else
415*9880d681SAndroid Build Coastguard Worker Opc = HasAVX ? X86::VMOVUPDrm : X86::MOVUPDrm;
416*9880d681SAndroid Build Coastguard Worker RC = &X86::VR128RegClass;
417*9880d681SAndroid Build Coastguard Worker break;
418*9880d681SAndroid Build Coastguard Worker case MVT::v4i32:
419*9880d681SAndroid Build Coastguard Worker case MVT::v2i64:
420*9880d681SAndroid Build Coastguard Worker case MVT::v8i16:
421*9880d681SAndroid Build Coastguard Worker case MVT::v16i8:
422*9880d681SAndroid Build Coastguard Worker if (IsNonTemporal && Alignment >= 16)
423*9880d681SAndroid Build Coastguard Worker Opc = HasAVX ? X86::VMOVNTDQArm : X86::MOVNTDQArm;
424*9880d681SAndroid Build Coastguard Worker else if (Alignment >= 16)
425*9880d681SAndroid Build Coastguard Worker Opc = HasAVX ? X86::VMOVDQArm : X86::MOVDQArm;
426*9880d681SAndroid Build Coastguard Worker else
427*9880d681SAndroid Build Coastguard Worker Opc = HasAVX ? X86::VMOVDQUrm : X86::MOVDQUrm;
428*9880d681SAndroid Build Coastguard Worker RC = &X86::VR128RegClass;
429*9880d681SAndroid Build Coastguard Worker break;
430*9880d681SAndroid Build Coastguard Worker case MVT::v8f32:
431*9880d681SAndroid Build Coastguard Worker assert(HasAVX);
432*9880d681SAndroid Build Coastguard Worker if (IsNonTemporal && Alignment >= 32 && HasAVX2)
433*9880d681SAndroid Build Coastguard Worker Opc = X86::VMOVNTDQAYrm;
434*9880d681SAndroid Build Coastguard Worker else
435*9880d681SAndroid Build Coastguard Worker Opc = (Alignment >= 32) ? X86::VMOVAPSYrm : X86::VMOVUPSYrm;
436*9880d681SAndroid Build Coastguard Worker RC = &X86::VR256RegClass;
437*9880d681SAndroid Build Coastguard Worker break;
438*9880d681SAndroid Build Coastguard Worker case MVT::v4f64:
439*9880d681SAndroid Build Coastguard Worker assert(HasAVX);
440*9880d681SAndroid Build Coastguard Worker if (IsNonTemporal && Alignment >= 32 && HasAVX2)
441*9880d681SAndroid Build Coastguard Worker Opc = X86::VMOVNTDQAYrm;
442*9880d681SAndroid Build Coastguard Worker else
443*9880d681SAndroid Build Coastguard Worker Opc = (Alignment >= 32) ? X86::VMOVAPDYrm : X86::VMOVUPDYrm;
444*9880d681SAndroid Build Coastguard Worker RC = &X86::VR256RegClass;
445*9880d681SAndroid Build Coastguard Worker break;
446*9880d681SAndroid Build Coastguard Worker case MVT::v8i32:
447*9880d681SAndroid Build Coastguard Worker case MVT::v4i64:
448*9880d681SAndroid Build Coastguard Worker case MVT::v16i16:
449*9880d681SAndroid Build Coastguard Worker case MVT::v32i8:
450*9880d681SAndroid Build Coastguard Worker assert(HasAVX);
451*9880d681SAndroid Build Coastguard Worker if (IsNonTemporal && Alignment >= 32 && HasAVX2)
452*9880d681SAndroid Build Coastguard Worker Opc = X86::VMOVNTDQAYrm;
453*9880d681SAndroid Build Coastguard Worker else
454*9880d681SAndroid Build Coastguard Worker Opc = (Alignment >= 32) ? X86::VMOVDQAYrm : X86::VMOVDQUYrm;
455*9880d681SAndroid Build Coastguard Worker RC = &X86::VR256RegClass;
456*9880d681SAndroid Build Coastguard Worker break;
457*9880d681SAndroid Build Coastguard Worker case MVT::v16f32:
458*9880d681SAndroid Build Coastguard Worker assert(Subtarget->hasAVX512());
459*9880d681SAndroid Build Coastguard Worker if (IsNonTemporal && Alignment >= 64)
460*9880d681SAndroid Build Coastguard Worker Opc = X86::VMOVNTDQAZrm;
461*9880d681SAndroid Build Coastguard Worker else
462*9880d681SAndroid Build Coastguard Worker Opc = (Alignment >= 64) ? X86::VMOVAPSZrm : X86::VMOVUPSZrm;
463*9880d681SAndroid Build Coastguard Worker RC = &X86::VR512RegClass;
464*9880d681SAndroid Build Coastguard Worker break;
465*9880d681SAndroid Build Coastguard Worker case MVT::v8f64:
466*9880d681SAndroid Build Coastguard Worker assert(Subtarget->hasAVX512());
467*9880d681SAndroid Build Coastguard Worker if (IsNonTemporal && Alignment >= 64)
468*9880d681SAndroid Build Coastguard Worker Opc = X86::VMOVNTDQAZrm;
469*9880d681SAndroid Build Coastguard Worker else
470*9880d681SAndroid Build Coastguard Worker Opc = (Alignment >= 64) ? X86::VMOVAPDZrm : X86::VMOVUPDZrm;
471*9880d681SAndroid Build Coastguard Worker RC = &X86::VR512RegClass;
472*9880d681SAndroid Build Coastguard Worker break;
473*9880d681SAndroid Build Coastguard Worker case MVT::v8i64:
474*9880d681SAndroid Build Coastguard Worker case MVT::v16i32:
475*9880d681SAndroid Build Coastguard Worker case MVT::v32i16:
476*9880d681SAndroid Build Coastguard Worker case MVT::v64i8:
477*9880d681SAndroid Build Coastguard Worker assert(Subtarget->hasAVX512());
478*9880d681SAndroid Build Coastguard Worker // Note: There are a lot more choices based on type with AVX-512, but
479*9880d681SAndroid Build Coastguard Worker // there's really no advantage when the load isn't masked.
480*9880d681SAndroid Build Coastguard Worker if (IsNonTemporal && Alignment >= 64)
481*9880d681SAndroid Build Coastguard Worker Opc = X86::VMOVNTDQAZrm;
482*9880d681SAndroid Build Coastguard Worker else
483*9880d681SAndroid Build Coastguard Worker Opc = (Alignment >= 64) ? X86::VMOVDQA64Zrm : X86::VMOVDQU64Zrm;
484*9880d681SAndroid Build Coastguard Worker RC = &X86::VR512RegClass;
485*9880d681SAndroid Build Coastguard Worker break;
486*9880d681SAndroid Build Coastguard Worker }
487*9880d681SAndroid Build Coastguard Worker
488*9880d681SAndroid Build Coastguard Worker ResultReg = createResultReg(RC);
489*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder MIB =
490*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg);
491*9880d681SAndroid Build Coastguard Worker addFullAddress(MIB, AM);
492*9880d681SAndroid Build Coastguard Worker if (MMO)
493*9880d681SAndroid Build Coastguard Worker MIB->addMemOperand(*FuncInfo.MF, MMO);
494*9880d681SAndroid Build Coastguard Worker return true;
495*9880d681SAndroid Build Coastguard Worker }
496*9880d681SAndroid Build Coastguard Worker
497*9880d681SAndroid Build Coastguard Worker /// X86FastEmitStore - Emit a machine instruction to store a value Val of
498*9880d681SAndroid Build Coastguard Worker /// type VT. The address is either pre-computed, consisted of a base ptr, Ptr
499*9880d681SAndroid Build Coastguard Worker /// and a displacement offset, or a GlobalAddress,
500*9880d681SAndroid Build Coastguard Worker /// i.e. V. Return true if it is possible.
X86FastEmitStore(EVT VT,unsigned ValReg,bool ValIsKill,X86AddressMode & AM,MachineMemOperand * MMO,bool Aligned)501*9880d681SAndroid Build Coastguard Worker bool X86FastISel::X86FastEmitStore(EVT VT, unsigned ValReg, bool ValIsKill,
502*9880d681SAndroid Build Coastguard Worker X86AddressMode &AM,
503*9880d681SAndroid Build Coastguard Worker MachineMemOperand *MMO, bool Aligned) {
504*9880d681SAndroid Build Coastguard Worker bool HasSSE2 = Subtarget->hasSSE2();
505*9880d681SAndroid Build Coastguard Worker bool HasSSE4A = Subtarget->hasSSE4A();
506*9880d681SAndroid Build Coastguard Worker bool HasAVX = Subtarget->hasAVX();
507*9880d681SAndroid Build Coastguard Worker bool IsNonTemporal = MMO && MMO->isNonTemporal();
508*9880d681SAndroid Build Coastguard Worker
509*9880d681SAndroid Build Coastguard Worker // Get opcode and regclass of the output for the given store instruction.
510*9880d681SAndroid Build Coastguard Worker unsigned Opc = 0;
511*9880d681SAndroid Build Coastguard Worker switch (VT.getSimpleVT().SimpleTy) {
512*9880d681SAndroid Build Coastguard Worker case MVT::f80: // No f80 support yet.
513*9880d681SAndroid Build Coastguard Worker default: return false;
514*9880d681SAndroid Build Coastguard Worker case MVT::i1: {
515*9880d681SAndroid Build Coastguard Worker // Mask out all but lowest bit.
516*9880d681SAndroid Build Coastguard Worker unsigned AndResult = createResultReg(&X86::GR8RegClass);
517*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
518*9880d681SAndroid Build Coastguard Worker TII.get(X86::AND8ri), AndResult)
519*9880d681SAndroid Build Coastguard Worker .addReg(ValReg, getKillRegState(ValIsKill)).addImm(1);
520*9880d681SAndroid Build Coastguard Worker ValReg = AndResult;
521*9880d681SAndroid Build Coastguard Worker }
522*9880d681SAndroid Build Coastguard Worker // FALLTHROUGH, handling i1 as i8.
523*9880d681SAndroid Build Coastguard Worker case MVT::i8: Opc = X86::MOV8mr; break;
524*9880d681SAndroid Build Coastguard Worker case MVT::i16: Opc = X86::MOV16mr; break;
525*9880d681SAndroid Build Coastguard Worker case MVT::i32:
526*9880d681SAndroid Build Coastguard Worker Opc = (IsNonTemporal && HasSSE2) ? X86::MOVNTImr : X86::MOV32mr;
527*9880d681SAndroid Build Coastguard Worker break;
528*9880d681SAndroid Build Coastguard Worker case MVT::i64:
529*9880d681SAndroid Build Coastguard Worker // Must be in x86-64 mode.
530*9880d681SAndroid Build Coastguard Worker Opc = (IsNonTemporal && HasSSE2) ? X86::MOVNTI_64mr : X86::MOV64mr;
531*9880d681SAndroid Build Coastguard Worker break;
532*9880d681SAndroid Build Coastguard Worker case MVT::f32:
533*9880d681SAndroid Build Coastguard Worker if (X86ScalarSSEf32) {
534*9880d681SAndroid Build Coastguard Worker if (IsNonTemporal && HasSSE4A)
535*9880d681SAndroid Build Coastguard Worker Opc = X86::MOVNTSS;
536*9880d681SAndroid Build Coastguard Worker else
537*9880d681SAndroid Build Coastguard Worker Opc = HasAVX ? X86::VMOVSSmr : X86::MOVSSmr;
538*9880d681SAndroid Build Coastguard Worker } else
539*9880d681SAndroid Build Coastguard Worker Opc = X86::ST_Fp32m;
540*9880d681SAndroid Build Coastguard Worker break;
541*9880d681SAndroid Build Coastguard Worker case MVT::f64:
542*9880d681SAndroid Build Coastguard Worker if (X86ScalarSSEf32) {
543*9880d681SAndroid Build Coastguard Worker if (IsNonTemporal && HasSSE4A)
544*9880d681SAndroid Build Coastguard Worker Opc = X86::MOVNTSD;
545*9880d681SAndroid Build Coastguard Worker else
546*9880d681SAndroid Build Coastguard Worker Opc = HasAVX ? X86::VMOVSDmr : X86::MOVSDmr;
547*9880d681SAndroid Build Coastguard Worker } else
548*9880d681SAndroid Build Coastguard Worker Opc = X86::ST_Fp64m;
549*9880d681SAndroid Build Coastguard Worker break;
550*9880d681SAndroid Build Coastguard Worker case MVT::v4f32:
551*9880d681SAndroid Build Coastguard Worker if (Aligned) {
552*9880d681SAndroid Build Coastguard Worker if (IsNonTemporal)
553*9880d681SAndroid Build Coastguard Worker Opc = HasAVX ? X86::VMOVNTPSmr : X86::MOVNTPSmr;
554*9880d681SAndroid Build Coastguard Worker else
555*9880d681SAndroid Build Coastguard Worker Opc = HasAVX ? X86::VMOVAPSmr : X86::MOVAPSmr;
556*9880d681SAndroid Build Coastguard Worker } else
557*9880d681SAndroid Build Coastguard Worker Opc = HasAVX ? X86::VMOVUPSmr : X86::MOVUPSmr;
558*9880d681SAndroid Build Coastguard Worker break;
559*9880d681SAndroid Build Coastguard Worker case MVT::v2f64:
560*9880d681SAndroid Build Coastguard Worker if (Aligned) {
561*9880d681SAndroid Build Coastguard Worker if (IsNonTemporal)
562*9880d681SAndroid Build Coastguard Worker Opc = HasAVX ? X86::VMOVNTPDmr : X86::MOVNTPDmr;
563*9880d681SAndroid Build Coastguard Worker else
564*9880d681SAndroid Build Coastguard Worker Opc = HasAVX ? X86::VMOVAPDmr : X86::MOVAPDmr;
565*9880d681SAndroid Build Coastguard Worker } else
566*9880d681SAndroid Build Coastguard Worker Opc = HasAVX ? X86::VMOVUPDmr : X86::MOVUPDmr;
567*9880d681SAndroid Build Coastguard Worker break;
568*9880d681SAndroid Build Coastguard Worker case MVT::v4i32:
569*9880d681SAndroid Build Coastguard Worker case MVT::v2i64:
570*9880d681SAndroid Build Coastguard Worker case MVT::v8i16:
571*9880d681SAndroid Build Coastguard Worker case MVT::v16i8:
572*9880d681SAndroid Build Coastguard Worker if (Aligned) {
573*9880d681SAndroid Build Coastguard Worker if (IsNonTemporal)
574*9880d681SAndroid Build Coastguard Worker Opc = HasAVX ? X86::VMOVNTDQmr : X86::MOVNTDQmr;
575*9880d681SAndroid Build Coastguard Worker else
576*9880d681SAndroid Build Coastguard Worker Opc = HasAVX ? X86::VMOVDQAmr : X86::MOVDQAmr;
577*9880d681SAndroid Build Coastguard Worker } else
578*9880d681SAndroid Build Coastguard Worker Opc = HasAVX ? X86::VMOVDQUmr : X86::MOVDQUmr;
579*9880d681SAndroid Build Coastguard Worker break;
580*9880d681SAndroid Build Coastguard Worker case MVT::v8f32:
581*9880d681SAndroid Build Coastguard Worker assert(HasAVX);
582*9880d681SAndroid Build Coastguard Worker if (Aligned)
583*9880d681SAndroid Build Coastguard Worker Opc = IsNonTemporal ? X86::VMOVNTPSYmr : X86::VMOVAPSYmr;
584*9880d681SAndroid Build Coastguard Worker else
585*9880d681SAndroid Build Coastguard Worker Opc = X86::VMOVUPSYmr;
586*9880d681SAndroid Build Coastguard Worker break;
587*9880d681SAndroid Build Coastguard Worker case MVT::v4f64:
588*9880d681SAndroid Build Coastguard Worker assert(HasAVX);
589*9880d681SAndroid Build Coastguard Worker if (Aligned) {
590*9880d681SAndroid Build Coastguard Worker Opc = IsNonTemporal ? X86::VMOVNTPDYmr : X86::VMOVAPDYmr;
591*9880d681SAndroid Build Coastguard Worker } else
592*9880d681SAndroid Build Coastguard Worker Opc = X86::VMOVUPDYmr;
593*9880d681SAndroid Build Coastguard Worker break;
594*9880d681SAndroid Build Coastguard Worker case MVT::v8i32:
595*9880d681SAndroid Build Coastguard Worker case MVT::v4i64:
596*9880d681SAndroid Build Coastguard Worker case MVT::v16i16:
597*9880d681SAndroid Build Coastguard Worker case MVT::v32i8:
598*9880d681SAndroid Build Coastguard Worker assert(HasAVX);
599*9880d681SAndroid Build Coastguard Worker if (Aligned)
600*9880d681SAndroid Build Coastguard Worker Opc = IsNonTemporal ? X86::VMOVNTDQYmr : X86::VMOVDQAYmr;
601*9880d681SAndroid Build Coastguard Worker else
602*9880d681SAndroid Build Coastguard Worker Opc = X86::VMOVDQUYmr;
603*9880d681SAndroid Build Coastguard Worker break;
604*9880d681SAndroid Build Coastguard Worker case MVT::v16f32:
605*9880d681SAndroid Build Coastguard Worker assert(Subtarget->hasAVX512());
606*9880d681SAndroid Build Coastguard Worker if (Aligned)
607*9880d681SAndroid Build Coastguard Worker Opc = IsNonTemporal ? X86::VMOVNTPSZmr : X86::VMOVAPSZmr;
608*9880d681SAndroid Build Coastguard Worker else
609*9880d681SAndroid Build Coastguard Worker Opc = X86::VMOVUPSZmr;
610*9880d681SAndroid Build Coastguard Worker break;
611*9880d681SAndroid Build Coastguard Worker case MVT::v8f64:
612*9880d681SAndroid Build Coastguard Worker assert(Subtarget->hasAVX512());
613*9880d681SAndroid Build Coastguard Worker if (Aligned) {
614*9880d681SAndroid Build Coastguard Worker Opc = IsNonTemporal ? X86::VMOVNTPDZmr : X86::VMOVAPDZmr;
615*9880d681SAndroid Build Coastguard Worker } else
616*9880d681SAndroid Build Coastguard Worker Opc = X86::VMOVUPDZmr;
617*9880d681SAndroid Build Coastguard Worker break;
618*9880d681SAndroid Build Coastguard Worker case MVT::v8i64:
619*9880d681SAndroid Build Coastguard Worker case MVT::v16i32:
620*9880d681SAndroid Build Coastguard Worker case MVT::v32i16:
621*9880d681SAndroid Build Coastguard Worker case MVT::v64i8:
622*9880d681SAndroid Build Coastguard Worker assert(Subtarget->hasAVX512());
623*9880d681SAndroid Build Coastguard Worker // Note: There are a lot more choices based on type with AVX-512, but
624*9880d681SAndroid Build Coastguard Worker // there's really no advantage when the store isn't masked.
625*9880d681SAndroid Build Coastguard Worker if (Aligned)
626*9880d681SAndroid Build Coastguard Worker Opc = IsNonTemporal ? X86::VMOVNTDQZmr : X86::VMOVDQA64Zmr;
627*9880d681SAndroid Build Coastguard Worker else
628*9880d681SAndroid Build Coastguard Worker Opc = X86::VMOVDQU64Zmr;
629*9880d681SAndroid Build Coastguard Worker break;
630*9880d681SAndroid Build Coastguard Worker }
631*9880d681SAndroid Build Coastguard Worker
632*9880d681SAndroid Build Coastguard Worker const MCInstrDesc &Desc = TII.get(Opc);
633*9880d681SAndroid Build Coastguard Worker // Some of the instructions in the previous switch use FR128 instead
634*9880d681SAndroid Build Coastguard Worker // of FR32 for ValReg. Make sure the register we feed the instruction
635*9880d681SAndroid Build Coastguard Worker // matches its register class constraints.
636*9880d681SAndroid Build Coastguard Worker // Note: This is fine to do a copy from FR32 to FR128, this is the
637*9880d681SAndroid Build Coastguard Worker // same registers behind the scene and actually why it did not trigger
638*9880d681SAndroid Build Coastguard Worker // any bugs before.
639*9880d681SAndroid Build Coastguard Worker ValReg = constrainOperandRegClass(Desc, ValReg, Desc.getNumOperands() - 1);
640*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder MIB =
641*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, Desc);
642*9880d681SAndroid Build Coastguard Worker addFullAddress(MIB, AM).addReg(ValReg, getKillRegState(ValIsKill));
643*9880d681SAndroid Build Coastguard Worker if (MMO)
644*9880d681SAndroid Build Coastguard Worker MIB->addMemOperand(*FuncInfo.MF, MMO);
645*9880d681SAndroid Build Coastguard Worker
646*9880d681SAndroid Build Coastguard Worker return true;
647*9880d681SAndroid Build Coastguard Worker }
648*9880d681SAndroid Build Coastguard Worker
X86FastEmitStore(EVT VT,const Value * Val,X86AddressMode & AM,MachineMemOperand * MMO,bool Aligned)649*9880d681SAndroid Build Coastguard Worker bool X86FastISel::X86FastEmitStore(EVT VT, const Value *Val,
650*9880d681SAndroid Build Coastguard Worker X86AddressMode &AM,
651*9880d681SAndroid Build Coastguard Worker MachineMemOperand *MMO, bool Aligned) {
652*9880d681SAndroid Build Coastguard Worker // Handle 'null' like i32/i64 0.
653*9880d681SAndroid Build Coastguard Worker if (isa<ConstantPointerNull>(Val))
654*9880d681SAndroid Build Coastguard Worker Val = Constant::getNullValue(DL.getIntPtrType(Val->getContext()));
655*9880d681SAndroid Build Coastguard Worker
656*9880d681SAndroid Build Coastguard Worker // If this is a store of a simple constant, fold the constant into the store.
657*9880d681SAndroid Build Coastguard Worker if (const ConstantInt *CI = dyn_cast<ConstantInt>(Val)) {
658*9880d681SAndroid Build Coastguard Worker unsigned Opc = 0;
659*9880d681SAndroid Build Coastguard Worker bool Signed = true;
660*9880d681SAndroid Build Coastguard Worker switch (VT.getSimpleVT().SimpleTy) {
661*9880d681SAndroid Build Coastguard Worker default: break;
662*9880d681SAndroid Build Coastguard Worker case MVT::i1: Signed = false; // FALLTHROUGH to handle as i8.
663*9880d681SAndroid Build Coastguard Worker case MVT::i8: Opc = X86::MOV8mi; break;
664*9880d681SAndroid Build Coastguard Worker case MVT::i16: Opc = X86::MOV16mi; break;
665*9880d681SAndroid Build Coastguard Worker case MVT::i32: Opc = X86::MOV32mi; break;
666*9880d681SAndroid Build Coastguard Worker case MVT::i64:
667*9880d681SAndroid Build Coastguard Worker // Must be a 32-bit sign extended value.
668*9880d681SAndroid Build Coastguard Worker if (isInt<32>(CI->getSExtValue()))
669*9880d681SAndroid Build Coastguard Worker Opc = X86::MOV64mi32;
670*9880d681SAndroid Build Coastguard Worker break;
671*9880d681SAndroid Build Coastguard Worker }
672*9880d681SAndroid Build Coastguard Worker
673*9880d681SAndroid Build Coastguard Worker if (Opc) {
674*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder MIB =
675*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc));
676*9880d681SAndroid Build Coastguard Worker addFullAddress(MIB, AM).addImm(Signed ? (uint64_t) CI->getSExtValue()
677*9880d681SAndroid Build Coastguard Worker : CI->getZExtValue());
678*9880d681SAndroid Build Coastguard Worker if (MMO)
679*9880d681SAndroid Build Coastguard Worker MIB->addMemOperand(*FuncInfo.MF, MMO);
680*9880d681SAndroid Build Coastguard Worker return true;
681*9880d681SAndroid Build Coastguard Worker }
682*9880d681SAndroid Build Coastguard Worker }
683*9880d681SAndroid Build Coastguard Worker
684*9880d681SAndroid Build Coastguard Worker unsigned ValReg = getRegForValue(Val);
685*9880d681SAndroid Build Coastguard Worker if (ValReg == 0)
686*9880d681SAndroid Build Coastguard Worker return false;
687*9880d681SAndroid Build Coastguard Worker
688*9880d681SAndroid Build Coastguard Worker bool ValKill = hasTrivialKill(Val);
689*9880d681SAndroid Build Coastguard Worker return X86FastEmitStore(VT, ValReg, ValKill, AM, MMO, Aligned);
690*9880d681SAndroid Build Coastguard Worker }
691*9880d681SAndroid Build Coastguard Worker
692*9880d681SAndroid Build Coastguard Worker /// X86FastEmitExtend - Emit a machine instruction to extend a value Src of
693*9880d681SAndroid Build Coastguard Worker /// type SrcVT to type DstVT using the specified extension opcode Opc (e.g.
694*9880d681SAndroid Build Coastguard Worker /// ISD::SIGN_EXTEND).
X86FastEmitExtend(ISD::NodeType Opc,EVT DstVT,unsigned Src,EVT SrcVT,unsigned & ResultReg)695*9880d681SAndroid Build Coastguard Worker bool X86FastISel::X86FastEmitExtend(ISD::NodeType Opc, EVT DstVT,
696*9880d681SAndroid Build Coastguard Worker unsigned Src, EVT SrcVT,
697*9880d681SAndroid Build Coastguard Worker unsigned &ResultReg) {
698*9880d681SAndroid Build Coastguard Worker unsigned RR = fastEmit_r(SrcVT.getSimpleVT(), DstVT.getSimpleVT(), Opc,
699*9880d681SAndroid Build Coastguard Worker Src, /*TODO: Kill=*/false);
700*9880d681SAndroid Build Coastguard Worker if (RR == 0)
701*9880d681SAndroid Build Coastguard Worker return false;
702*9880d681SAndroid Build Coastguard Worker
703*9880d681SAndroid Build Coastguard Worker ResultReg = RR;
704*9880d681SAndroid Build Coastguard Worker return true;
705*9880d681SAndroid Build Coastguard Worker }
706*9880d681SAndroid Build Coastguard Worker
handleConstantAddresses(const Value * V,X86AddressMode & AM)707*9880d681SAndroid Build Coastguard Worker bool X86FastISel::handleConstantAddresses(const Value *V, X86AddressMode &AM) {
708*9880d681SAndroid Build Coastguard Worker // Handle constant address.
709*9880d681SAndroid Build Coastguard Worker if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
710*9880d681SAndroid Build Coastguard Worker // Can't handle alternate code models yet.
711*9880d681SAndroid Build Coastguard Worker if (TM.getCodeModel() != CodeModel::Small)
712*9880d681SAndroid Build Coastguard Worker return false;
713*9880d681SAndroid Build Coastguard Worker
714*9880d681SAndroid Build Coastguard Worker // Can't handle TLS yet.
715*9880d681SAndroid Build Coastguard Worker if (GV->isThreadLocal())
716*9880d681SAndroid Build Coastguard Worker return false;
717*9880d681SAndroid Build Coastguard Worker
718*9880d681SAndroid Build Coastguard Worker // RIP-relative addresses can't have additional register operands, so if
719*9880d681SAndroid Build Coastguard Worker // we've already folded stuff into the addressing mode, just force the
720*9880d681SAndroid Build Coastguard Worker // global value into its own register, which we can use as the basereg.
721*9880d681SAndroid Build Coastguard Worker if (!Subtarget->isPICStyleRIPRel() ||
722*9880d681SAndroid Build Coastguard Worker (AM.Base.Reg == 0 && AM.IndexReg == 0)) {
723*9880d681SAndroid Build Coastguard Worker // Okay, we've committed to selecting this global. Set up the address.
724*9880d681SAndroid Build Coastguard Worker AM.GV = GV;
725*9880d681SAndroid Build Coastguard Worker
726*9880d681SAndroid Build Coastguard Worker // Allow the subtarget to classify the global.
727*9880d681SAndroid Build Coastguard Worker unsigned char GVFlags = Subtarget->classifyGlobalReference(GV);
728*9880d681SAndroid Build Coastguard Worker
729*9880d681SAndroid Build Coastguard Worker // If this reference is relative to the pic base, set it now.
730*9880d681SAndroid Build Coastguard Worker if (isGlobalRelativeToPICBase(GVFlags)) {
731*9880d681SAndroid Build Coastguard Worker // FIXME: How do we know Base.Reg is free??
732*9880d681SAndroid Build Coastguard Worker AM.Base.Reg = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
733*9880d681SAndroid Build Coastguard Worker }
734*9880d681SAndroid Build Coastguard Worker
735*9880d681SAndroid Build Coastguard Worker // Unless the ABI requires an extra load, return a direct reference to
736*9880d681SAndroid Build Coastguard Worker // the global.
737*9880d681SAndroid Build Coastguard Worker if (!isGlobalStubReference(GVFlags)) {
738*9880d681SAndroid Build Coastguard Worker if (Subtarget->isPICStyleRIPRel()) {
739*9880d681SAndroid Build Coastguard Worker // Use rip-relative addressing if we can. Above we verified that the
740*9880d681SAndroid Build Coastguard Worker // base and index registers are unused.
741*9880d681SAndroid Build Coastguard Worker assert(AM.Base.Reg == 0 && AM.IndexReg == 0);
742*9880d681SAndroid Build Coastguard Worker AM.Base.Reg = X86::RIP;
743*9880d681SAndroid Build Coastguard Worker }
744*9880d681SAndroid Build Coastguard Worker AM.GVOpFlags = GVFlags;
745*9880d681SAndroid Build Coastguard Worker return true;
746*9880d681SAndroid Build Coastguard Worker }
747*9880d681SAndroid Build Coastguard Worker
748*9880d681SAndroid Build Coastguard Worker // Ok, we need to do a load from a stub. If we've already loaded from
749*9880d681SAndroid Build Coastguard Worker // this stub, reuse the loaded pointer, otherwise emit the load now.
750*9880d681SAndroid Build Coastguard Worker DenseMap<const Value *, unsigned>::iterator I = LocalValueMap.find(V);
751*9880d681SAndroid Build Coastguard Worker unsigned LoadReg;
752*9880d681SAndroid Build Coastguard Worker if (I != LocalValueMap.end() && I->second != 0) {
753*9880d681SAndroid Build Coastguard Worker LoadReg = I->second;
754*9880d681SAndroid Build Coastguard Worker } else {
755*9880d681SAndroid Build Coastguard Worker // Issue load from stub.
756*9880d681SAndroid Build Coastguard Worker unsigned Opc = 0;
757*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = nullptr;
758*9880d681SAndroid Build Coastguard Worker X86AddressMode StubAM;
759*9880d681SAndroid Build Coastguard Worker StubAM.Base.Reg = AM.Base.Reg;
760*9880d681SAndroid Build Coastguard Worker StubAM.GV = GV;
761*9880d681SAndroid Build Coastguard Worker StubAM.GVOpFlags = GVFlags;
762*9880d681SAndroid Build Coastguard Worker
763*9880d681SAndroid Build Coastguard Worker // Prepare for inserting code in the local-value area.
764*9880d681SAndroid Build Coastguard Worker SavePoint SaveInsertPt = enterLocalValueArea();
765*9880d681SAndroid Build Coastguard Worker
766*9880d681SAndroid Build Coastguard Worker if (TLI.getPointerTy(DL) == MVT::i64) {
767*9880d681SAndroid Build Coastguard Worker Opc = X86::MOV64rm;
768*9880d681SAndroid Build Coastguard Worker RC = &X86::GR64RegClass;
769*9880d681SAndroid Build Coastguard Worker
770*9880d681SAndroid Build Coastguard Worker if (Subtarget->isPICStyleRIPRel())
771*9880d681SAndroid Build Coastguard Worker StubAM.Base.Reg = X86::RIP;
772*9880d681SAndroid Build Coastguard Worker } else {
773*9880d681SAndroid Build Coastguard Worker Opc = X86::MOV32rm;
774*9880d681SAndroid Build Coastguard Worker RC = &X86::GR32RegClass;
775*9880d681SAndroid Build Coastguard Worker }
776*9880d681SAndroid Build Coastguard Worker
777*9880d681SAndroid Build Coastguard Worker LoadReg = createResultReg(RC);
778*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder LoadMI =
779*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), LoadReg);
780*9880d681SAndroid Build Coastguard Worker addFullAddress(LoadMI, StubAM);
781*9880d681SAndroid Build Coastguard Worker
782*9880d681SAndroid Build Coastguard Worker // Ok, back to normal mode.
783*9880d681SAndroid Build Coastguard Worker leaveLocalValueArea(SaveInsertPt);
784*9880d681SAndroid Build Coastguard Worker
785*9880d681SAndroid Build Coastguard Worker // Prevent loading GV stub multiple times in same MBB.
786*9880d681SAndroid Build Coastguard Worker LocalValueMap[V] = LoadReg;
787*9880d681SAndroid Build Coastguard Worker }
788*9880d681SAndroid Build Coastguard Worker
789*9880d681SAndroid Build Coastguard Worker // Now construct the final address. Note that the Disp, Scale,
790*9880d681SAndroid Build Coastguard Worker // and Index values may already be set here.
791*9880d681SAndroid Build Coastguard Worker AM.Base.Reg = LoadReg;
792*9880d681SAndroid Build Coastguard Worker AM.GV = nullptr;
793*9880d681SAndroid Build Coastguard Worker return true;
794*9880d681SAndroid Build Coastguard Worker }
795*9880d681SAndroid Build Coastguard Worker }
796*9880d681SAndroid Build Coastguard Worker
797*9880d681SAndroid Build Coastguard Worker // If all else fails, try to materialize the value in a register.
798*9880d681SAndroid Build Coastguard Worker if (!AM.GV || !Subtarget->isPICStyleRIPRel()) {
799*9880d681SAndroid Build Coastguard Worker if (AM.Base.Reg == 0) {
800*9880d681SAndroid Build Coastguard Worker AM.Base.Reg = getRegForValue(V);
801*9880d681SAndroid Build Coastguard Worker return AM.Base.Reg != 0;
802*9880d681SAndroid Build Coastguard Worker }
803*9880d681SAndroid Build Coastguard Worker if (AM.IndexReg == 0) {
804*9880d681SAndroid Build Coastguard Worker assert(AM.Scale == 1 && "Scale with no index!");
805*9880d681SAndroid Build Coastguard Worker AM.IndexReg = getRegForValue(V);
806*9880d681SAndroid Build Coastguard Worker return AM.IndexReg != 0;
807*9880d681SAndroid Build Coastguard Worker }
808*9880d681SAndroid Build Coastguard Worker }
809*9880d681SAndroid Build Coastguard Worker
810*9880d681SAndroid Build Coastguard Worker return false;
811*9880d681SAndroid Build Coastguard Worker }
812*9880d681SAndroid Build Coastguard Worker
813*9880d681SAndroid Build Coastguard Worker /// X86SelectAddress - Attempt to fill in an address from the given value.
814*9880d681SAndroid Build Coastguard Worker ///
X86SelectAddress(const Value * V,X86AddressMode & AM)815*9880d681SAndroid Build Coastguard Worker bool X86FastISel::X86SelectAddress(const Value *V, X86AddressMode &AM) {
816*9880d681SAndroid Build Coastguard Worker SmallVector<const Value *, 32> GEPs;
817*9880d681SAndroid Build Coastguard Worker redo_gep:
818*9880d681SAndroid Build Coastguard Worker const User *U = nullptr;
819*9880d681SAndroid Build Coastguard Worker unsigned Opcode = Instruction::UserOp1;
820*9880d681SAndroid Build Coastguard Worker if (const Instruction *I = dyn_cast<Instruction>(V)) {
821*9880d681SAndroid Build Coastguard Worker // Don't walk into other basic blocks; it's possible we haven't
822*9880d681SAndroid Build Coastguard Worker // visited them yet, so the instructions may not yet be assigned
823*9880d681SAndroid Build Coastguard Worker // virtual registers.
824*9880d681SAndroid Build Coastguard Worker if (FuncInfo.StaticAllocaMap.count(static_cast<const AllocaInst *>(V)) ||
825*9880d681SAndroid Build Coastguard Worker FuncInfo.MBBMap[I->getParent()] == FuncInfo.MBB) {
826*9880d681SAndroid Build Coastguard Worker Opcode = I->getOpcode();
827*9880d681SAndroid Build Coastguard Worker U = I;
828*9880d681SAndroid Build Coastguard Worker }
829*9880d681SAndroid Build Coastguard Worker } else if (const ConstantExpr *C = dyn_cast<ConstantExpr>(V)) {
830*9880d681SAndroid Build Coastguard Worker Opcode = C->getOpcode();
831*9880d681SAndroid Build Coastguard Worker U = C;
832*9880d681SAndroid Build Coastguard Worker }
833*9880d681SAndroid Build Coastguard Worker
834*9880d681SAndroid Build Coastguard Worker if (PointerType *Ty = dyn_cast<PointerType>(V->getType()))
835*9880d681SAndroid Build Coastguard Worker if (Ty->getAddressSpace() > 255)
836*9880d681SAndroid Build Coastguard Worker // Fast instruction selection doesn't support the special
837*9880d681SAndroid Build Coastguard Worker // address spaces.
838*9880d681SAndroid Build Coastguard Worker return false;
839*9880d681SAndroid Build Coastguard Worker
840*9880d681SAndroid Build Coastguard Worker switch (Opcode) {
841*9880d681SAndroid Build Coastguard Worker default: break;
842*9880d681SAndroid Build Coastguard Worker case Instruction::BitCast:
843*9880d681SAndroid Build Coastguard Worker // Look past bitcasts.
844*9880d681SAndroid Build Coastguard Worker return X86SelectAddress(U->getOperand(0), AM);
845*9880d681SAndroid Build Coastguard Worker
846*9880d681SAndroid Build Coastguard Worker case Instruction::IntToPtr:
847*9880d681SAndroid Build Coastguard Worker // Look past no-op inttoptrs.
848*9880d681SAndroid Build Coastguard Worker if (TLI.getValueType(DL, U->getOperand(0)->getType()) ==
849*9880d681SAndroid Build Coastguard Worker TLI.getPointerTy(DL))
850*9880d681SAndroid Build Coastguard Worker return X86SelectAddress(U->getOperand(0), AM);
851*9880d681SAndroid Build Coastguard Worker break;
852*9880d681SAndroid Build Coastguard Worker
853*9880d681SAndroid Build Coastguard Worker case Instruction::PtrToInt:
854*9880d681SAndroid Build Coastguard Worker // Look past no-op ptrtoints.
855*9880d681SAndroid Build Coastguard Worker if (TLI.getValueType(DL, U->getType()) == TLI.getPointerTy(DL))
856*9880d681SAndroid Build Coastguard Worker return X86SelectAddress(U->getOperand(0), AM);
857*9880d681SAndroid Build Coastguard Worker break;
858*9880d681SAndroid Build Coastguard Worker
859*9880d681SAndroid Build Coastguard Worker case Instruction::Alloca: {
860*9880d681SAndroid Build Coastguard Worker // Do static allocas.
861*9880d681SAndroid Build Coastguard Worker const AllocaInst *A = cast<AllocaInst>(V);
862*9880d681SAndroid Build Coastguard Worker DenseMap<const AllocaInst *, int>::iterator SI =
863*9880d681SAndroid Build Coastguard Worker FuncInfo.StaticAllocaMap.find(A);
864*9880d681SAndroid Build Coastguard Worker if (SI != FuncInfo.StaticAllocaMap.end()) {
865*9880d681SAndroid Build Coastguard Worker AM.BaseType = X86AddressMode::FrameIndexBase;
866*9880d681SAndroid Build Coastguard Worker AM.Base.FrameIndex = SI->second;
867*9880d681SAndroid Build Coastguard Worker return true;
868*9880d681SAndroid Build Coastguard Worker }
869*9880d681SAndroid Build Coastguard Worker break;
870*9880d681SAndroid Build Coastguard Worker }
871*9880d681SAndroid Build Coastguard Worker
872*9880d681SAndroid Build Coastguard Worker case Instruction::Add: {
873*9880d681SAndroid Build Coastguard Worker // Adds of constants are common and easy enough.
874*9880d681SAndroid Build Coastguard Worker if (const ConstantInt *CI = dyn_cast<ConstantInt>(U->getOperand(1))) {
875*9880d681SAndroid Build Coastguard Worker uint64_t Disp = (int32_t)AM.Disp + (uint64_t)CI->getSExtValue();
876*9880d681SAndroid Build Coastguard Worker // They have to fit in the 32-bit signed displacement field though.
877*9880d681SAndroid Build Coastguard Worker if (isInt<32>(Disp)) {
878*9880d681SAndroid Build Coastguard Worker AM.Disp = (uint32_t)Disp;
879*9880d681SAndroid Build Coastguard Worker return X86SelectAddress(U->getOperand(0), AM);
880*9880d681SAndroid Build Coastguard Worker }
881*9880d681SAndroid Build Coastguard Worker }
882*9880d681SAndroid Build Coastguard Worker break;
883*9880d681SAndroid Build Coastguard Worker }
884*9880d681SAndroid Build Coastguard Worker
885*9880d681SAndroid Build Coastguard Worker case Instruction::GetElementPtr: {
886*9880d681SAndroid Build Coastguard Worker X86AddressMode SavedAM = AM;
887*9880d681SAndroid Build Coastguard Worker
888*9880d681SAndroid Build Coastguard Worker // Pattern-match simple GEPs.
889*9880d681SAndroid Build Coastguard Worker uint64_t Disp = (int32_t)AM.Disp;
890*9880d681SAndroid Build Coastguard Worker unsigned IndexReg = AM.IndexReg;
891*9880d681SAndroid Build Coastguard Worker unsigned Scale = AM.Scale;
892*9880d681SAndroid Build Coastguard Worker gep_type_iterator GTI = gep_type_begin(U);
893*9880d681SAndroid Build Coastguard Worker // Iterate through the indices, folding what we can. Constants can be
894*9880d681SAndroid Build Coastguard Worker // folded, and one dynamic index can be handled, if the scale is supported.
895*9880d681SAndroid Build Coastguard Worker for (User::const_op_iterator i = U->op_begin() + 1, e = U->op_end();
896*9880d681SAndroid Build Coastguard Worker i != e; ++i, ++GTI) {
897*9880d681SAndroid Build Coastguard Worker const Value *Op = *i;
898*9880d681SAndroid Build Coastguard Worker if (StructType *STy = dyn_cast<StructType>(*GTI)) {
899*9880d681SAndroid Build Coastguard Worker const StructLayout *SL = DL.getStructLayout(STy);
900*9880d681SAndroid Build Coastguard Worker Disp += SL->getElementOffset(cast<ConstantInt>(Op)->getZExtValue());
901*9880d681SAndroid Build Coastguard Worker continue;
902*9880d681SAndroid Build Coastguard Worker }
903*9880d681SAndroid Build Coastguard Worker
904*9880d681SAndroid Build Coastguard Worker // A array/variable index is always of the form i*S where S is the
905*9880d681SAndroid Build Coastguard Worker // constant scale size. See if we can push the scale into immediates.
906*9880d681SAndroid Build Coastguard Worker uint64_t S = DL.getTypeAllocSize(GTI.getIndexedType());
907*9880d681SAndroid Build Coastguard Worker for (;;) {
908*9880d681SAndroid Build Coastguard Worker if (const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
909*9880d681SAndroid Build Coastguard Worker // Constant-offset addressing.
910*9880d681SAndroid Build Coastguard Worker Disp += CI->getSExtValue() * S;
911*9880d681SAndroid Build Coastguard Worker break;
912*9880d681SAndroid Build Coastguard Worker }
913*9880d681SAndroid Build Coastguard Worker if (canFoldAddIntoGEP(U, Op)) {
914*9880d681SAndroid Build Coastguard Worker // A compatible add with a constant operand. Fold the constant.
915*9880d681SAndroid Build Coastguard Worker ConstantInt *CI =
916*9880d681SAndroid Build Coastguard Worker cast<ConstantInt>(cast<AddOperator>(Op)->getOperand(1));
917*9880d681SAndroid Build Coastguard Worker Disp += CI->getSExtValue() * S;
918*9880d681SAndroid Build Coastguard Worker // Iterate on the other operand.
919*9880d681SAndroid Build Coastguard Worker Op = cast<AddOperator>(Op)->getOperand(0);
920*9880d681SAndroid Build Coastguard Worker continue;
921*9880d681SAndroid Build Coastguard Worker }
922*9880d681SAndroid Build Coastguard Worker if (IndexReg == 0 &&
923*9880d681SAndroid Build Coastguard Worker (!AM.GV || !Subtarget->isPICStyleRIPRel()) &&
924*9880d681SAndroid Build Coastguard Worker (S == 1 || S == 2 || S == 4 || S == 8)) {
925*9880d681SAndroid Build Coastguard Worker // Scaled-index addressing.
926*9880d681SAndroid Build Coastguard Worker Scale = S;
927*9880d681SAndroid Build Coastguard Worker IndexReg = getRegForGEPIndex(Op).first;
928*9880d681SAndroid Build Coastguard Worker if (IndexReg == 0)
929*9880d681SAndroid Build Coastguard Worker return false;
930*9880d681SAndroid Build Coastguard Worker break;
931*9880d681SAndroid Build Coastguard Worker }
932*9880d681SAndroid Build Coastguard Worker // Unsupported.
933*9880d681SAndroid Build Coastguard Worker goto unsupported_gep;
934*9880d681SAndroid Build Coastguard Worker }
935*9880d681SAndroid Build Coastguard Worker }
936*9880d681SAndroid Build Coastguard Worker
937*9880d681SAndroid Build Coastguard Worker // Check for displacement overflow.
938*9880d681SAndroid Build Coastguard Worker if (!isInt<32>(Disp))
939*9880d681SAndroid Build Coastguard Worker break;
940*9880d681SAndroid Build Coastguard Worker
941*9880d681SAndroid Build Coastguard Worker AM.IndexReg = IndexReg;
942*9880d681SAndroid Build Coastguard Worker AM.Scale = Scale;
943*9880d681SAndroid Build Coastguard Worker AM.Disp = (uint32_t)Disp;
944*9880d681SAndroid Build Coastguard Worker GEPs.push_back(V);
945*9880d681SAndroid Build Coastguard Worker
946*9880d681SAndroid Build Coastguard Worker if (const GetElementPtrInst *GEP =
947*9880d681SAndroid Build Coastguard Worker dyn_cast<GetElementPtrInst>(U->getOperand(0))) {
948*9880d681SAndroid Build Coastguard Worker // Ok, the GEP indices were covered by constant-offset and scaled-index
949*9880d681SAndroid Build Coastguard Worker // addressing. Update the address state and move on to examining the base.
950*9880d681SAndroid Build Coastguard Worker V = GEP;
951*9880d681SAndroid Build Coastguard Worker goto redo_gep;
952*9880d681SAndroid Build Coastguard Worker } else if (X86SelectAddress(U->getOperand(0), AM)) {
953*9880d681SAndroid Build Coastguard Worker return true;
954*9880d681SAndroid Build Coastguard Worker }
955*9880d681SAndroid Build Coastguard Worker
956*9880d681SAndroid Build Coastguard Worker // If we couldn't merge the gep value into this addr mode, revert back to
957*9880d681SAndroid Build Coastguard Worker // our address and just match the value instead of completely failing.
958*9880d681SAndroid Build Coastguard Worker AM = SavedAM;
959*9880d681SAndroid Build Coastguard Worker
960*9880d681SAndroid Build Coastguard Worker for (const Value *I : reverse(GEPs))
961*9880d681SAndroid Build Coastguard Worker if (handleConstantAddresses(I, AM))
962*9880d681SAndroid Build Coastguard Worker return true;
963*9880d681SAndroid Build Coastguard Worker
964*9880d681SAndroid Build Coastguard Worker return false;
965*9880d681SAndroid Build Coastguard Worker unsupported_gep:
966*9880d681SAndroid Build Coastguard Worker // Ok, the GEP indices weren't all covered.
967*9880d681SAndroid Build Coastguard Worker break;
968*9880d681SAndroid Build Coastguard Worker }
969*9880d681SAndroid Build Coastguard Worker }
970*9880d681SAndroid Build Coastguard Worker
971*9880d681SAndroid Build Coastguard Worker return handleConstantAddresses(V, AM);
972*9880d681SAndroid Build Coastguard Worker }
973*9880d681SAndroid Build Coastguard Worker
974*9880d681SAndroid Build Coastguard Worker /// X86SelectCallAddress - Attempt to fill in an address from the given value.
975*9880d681SAndroid Build Coastguard Worker ///
X86SelectCallAddress(const Value * V,X86AddressMode & AM)976*9880d681SAndroid Build Coastguard Worker bool X86FastISel::X86SelectCallAddress(const Value *V, X86AddressMode &AM) {
977*9880d681SAndroid Build Coastguard Worker const User *U = nullptr;
978*9880d681SAndroid Build Coastguard Worker unsigned Opcode = Instruction::UserOp1;
979*9880d681SAndroid Build Coastguard Worker const Instruction *I = dyn_cast<Instruction>(V);
980*9880d681SAndroid Build Coastguard Worker // Record if the value is defined in the same basic block.
981*9880d681SAndroid Build Coastguard Worker //
982*9880d681SAndroid Build Coastguard Worker // This information is crucial to know whether or not folding an
983*9880d681SAndroid Build Coastguard Worker // operand is valid.
984*9880d681SAndroid Build Coastguard Worker // Indeed, FastISel generates or reuses a virtual register for all
985*9880d681SAndroid Build Coastguard Worker // operands of all instructions it selects. Obviously, the definition and
986*9880d681SAndroid Build Coastguard Worker // its uses must use the same virtual register otherwise the produced
987*9880d681SAndroid Build Coastguard Worker // code is incorrect.
988*9880d681SAndroid Build Coastguard Worker // Before instruction selection, FunctionLoweringInfo::set sets the virtual
989*9880d681SAndroid Build Coastguard Worker // registers for values that are alive across basic blocks. This ensures
990*9880d681SAndroid Build Coastguard Worker // that the values are consistently set between across basic block, even
991*9880d681SAndroid Build Coastguard Worker // if different instruction selection mechanisms are used (e.g., a mix of
992*9880d681SAndroid Build Coastguard Worker // SDISel and FastISel).
993*9880d681SAndroid Build Coastguard Worker // For values local to a basic block, the instruction selection process
994*9880d681SAndroid Build Coastguard Worker // generates these virtual registers with whatever method is appropriate
995*9880d681SAndroid Build Coastguard Worker // for its needs. In particular, FastISel and SDISel do not share the way
996*9880d681SAndroid Build Coastguard Worker // local virtual registers are set.
997*9880d681SAndroid Build Coastguard Worker // Therefore, this is impossible (or at least unsafe) to share values
998*9880d681SAndroid Build Coastguard Worker // between basic blocks unless they use the same instruction selection
999*9880d681SAndroid Build Coastguard Worker // method, which is not guarantee for X86.
1000*9880d681SAndroid Build Coastguard Worker // Moreover, things like hasOneUse could not be used accurately, if we
1001*9880d681SAndroid Build Coastguard Worker // allow to reference values across basic blocks whereas they are not
1002*9880d681SAndroid Build Coastguard Worker // alive across basic blocks initially.
1003*9880d681SAndroid Build Coastguard Worker bool InMBB = true;
1004*9880d681SAndroid Build Coastguard Worker if (I) {
1005*9880d681SAndroid Build Coastguard Worker Opcode = I->getOpcode();
1006*9880d681SAndroid Build Coastguard Worker U = I;
1007*9880d681SAndroid Build Coastguard Worker InMBB = I->getParent() == FuncInfo.MBB->getBasicBlock();
1008*9880d681SAndroid Build Coastguard Worker } else if (const ConstantExpr *C = dyn_cast<ConstantExpr>(V)) {
1009*9880d681SAndroid Build Coastguard Worker Opcode = C->getOpcode();
1010*9880d681SAndroid Build Coastguard Worker U = C;
1011*9880d681SAndroid Build Coastguard Worker }
1012*9880d681SAndroid Build Coastguard Worker
1013*9880d681SAndroid Build Coastguard Worker switch (Opcode) {
1014*9880d681SAndroid Build Coastguard Worker default: break;
1015*9880d681SAndroid Build Coastguard Worker case Instruction::BitCast:
1016*9880d681SAndroid Build Coastguard Worker // Look past bitcasts if its operand is in the same BB.
1017*9880d681SAndroid Build Coastguard Worker if (InMBB)
1018*9880d681SAndroid Build Coastguard Worker return X86SelectCallAddress(U->getOperand(0), AM);
1019*9880d681SAndroid Build Coastguard Worker break;
1020*9880d681SAndroid Build Coastguard Worker
1021*9880d681SAndroid Build Coastguard Worker case Instruction::IntToPtr:
1022*9880d681SAndroid Build Coastguard Worker // Look past no-op inttoptrs if its operand is in the same BB.
1023*9880d681SAndroid Build Coastguard Worker if (InMBB &&
1024*9880d681SAndroid Build Coastguard Worker TLI.getValueType(DL, U->getOperand(0)->getType()) ==
1025*9880d681SAndroid Build Coastguard Worker TLI.getPointerTy(DL))
1026*9880d681SAndroid Build Coastguard Worker return X86SelectCallAddress(U->getOperand(0), AM);
1027*9880d681SAndroid Build Coastguard Worker break;
1028*9880d681SAndroid Build Coastguard Worker
1029*9880d681SAndroid Build Coastguard Worker case Instruction::PtrToInt:
1030*9880d681SAndroid Build Coastguard Worker // Look past no-op ptrtoints if its operand is in the same BB.
1031*9880d681SAndroid Build Coastguard Worker if (InMBB && TLI.getValueType(DL, U->getType()) == TLI.getPointerTy(DL))
1032*9880d681SAndroid Build Coastguard Worker return X86SelectCallAddress(U->getOperand(0), AM);
1033*9880d681SAndroid Build Coastguard Worker break;
1034*9880d681SAndroid Build Coastguard Worker }
1035*9880d681SAndroid Build Coastguard Worker
1036*9880d681SAndroid Build Coastguard Worker // Handle constant address.
1037*9880d681SAndroid Build Coastguard Worker if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
1038*9880d681SAndroid Build Coastguard Worker // Can't handle alternate code models yet.
1039*9880d681SAndroid Build Coastguard Worker if (TM.getCodeModel() != CodeModel::Small)
1040*9880d681SAndroid Build Coastguard Worker return false;
1041*9880d681SAndroid Build Coastguard Worker
1042*9880d681SAndroid Build Coastguard Worker // RIP-relative addresses can't have additional register operands.
1043*9880d681SAndroid Build Coastguard Worker if (Subtarget->isPICStyleRIPRel() &&
1044*9880d681SAndroid Build Coastguard Worker (AM.Base.Reg != 0 || AM.IndexReg != 0))
1045*9880d681SAndroid Build Coastguard Worker return false;
1046*9880d681SAndroid Build Coastguard Worker
1047*9880d681SAndroid Build Coastguard Worker // Can't handle DLL Import.
1048*9880d681SAndroid Build Coastguard Worker if (GV->hasDLLImportStorageClass())
1049*9880d681SAndroid Build Coastguard Worker return false;
1050*9880d681SAndroid Build Coastguard Worker
1051*9880d681SAndroid Build Coastguard Worker // Can't handle TLS.
1052*9880d681SAndroid Build Coastguard Worker if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))
1053*9880d681SAndroid Build Coastguard Worker if (GVar->isThreadLocal())
1054*9880d681SAndroid Build Coastguard Worker return false;
1055*9880d681SAndroid Build Coastguard Worker
1056*9880d681SAndroid Build Coastguard Worker // Okay, we've committed to selecting this global. Set up the basic address.
1057*9880d681SAndroid Build Coastguard Worker AM.GV = GV;
1058*9880d681SAndroid Build Coastguard Worker
1059*9880d681SAndroid Build Coastguard Worker // No ABI requires an extra load for anything other than DLLImport, which
1060*9880d681SAndroid Build Coastguard Worker // we rejected above. Return a direct reference to the global.
1061*9880d681SAndroid Build Coastguard Worker if (Subtarget->isPICStyleRIPRel()) {
1062*9880d681SAndroid Build Coastguard Worker // Use rip-relative addressing if we can. Above we verified that the
1063*9880d681SAndroid Build Coastguard Worker // base and index registers are unused.
1064*9880d681SAndroid Build Coastguard Worker assert(AM.Base.Reg == 0 && AM.IndexReg == 0);
1065*9880d681SAndroid Build Coastguard Worker AM.Base.Reg = X86::RIP;
1066*9880d681SAndroid Build Coastguard Worker } else {
1067*9880d681SAndroid Build Coastguard Worker AM.GVOpFlags = Subtarget->classifyLocalReference(nullptr);
1068*9880d681SAndroid Build Coastguard Worker }
1069*9880d681SAndroid Build Coastguard Worker
1070*9880d681SAndroid Build Coastguard Worker return true;
1071*9880d681SAndroid Build Coastguard Worker }
1072*9880d681SAndroid Build Coastguard Worker
1073*9880d681SAndroid Build Coastguard Worker // If all else fails, try to materialize the value in a register.
1074*9880d681SAndroid Build Coastguard Worker if (!AM.GV || !Subtarget->isPICStyleRIPRel()) {
1075*9880d681SAndroid Build Coastguard Worker if (AM.Base.Reg == 0) {
1076*9880d681SAndroid Build Coastguard Worker AM.Base.Reg = getRegForValue(V);
1077*9880d681SAndroid Build Coastguard Worker return AM.Base.Reg != 0;
1078*9880d681SAndroid Build Coastguard Worker }
1079*9880d681SAndroid Build Coastguard Worker if (AM.IndexReg == 0) {
1080*9880d681SAndroid Build Coastguard Worker assert(AM.Scale == 1 && "Scale with no index!");
1081*9880d681SAndroid Build Coastguard Worker AM.IndexReg = getRegForValue(V);
1082*9880d681SAndroid Build Coastguard Worker return AM.IndexReg != 0;
1083*9880d681SAndroid Build Coastguard Worker }
1084*9880d681SAndroid Build Coastguard Worker }
1085*9880d681SAndroid Build Coastguard Worker
1086*9880d681SAndroid Build Coastguard Worker return false;
1087*9880d681SAndroid Build Coastguard Worker }
1088*9880d681SAndroid Build Coastguard Worker
1089*9880d681SAndroid Build Coastguard Worker
1090*9880d681SAndroid Build Coastguard Worker /// X86SelectStore - Select and emit code to implement store instructions.
X86SelectStore(const Instruction * I)1091*9880d681SAndroid Build Coastguard Worker bool X86FastISel::X86SelectStore(const Instruction *I) {
1092*9880d681SAndroid Build Coastguard Worker // Atomic stores need special handling.
1093*9880d681SAndroid Build Coastguard Worker const StoreInst *S = cast<StoreInst>(I);
1094*9880d681SAndroid Build Coastguard Worker
1095*9880d681SAndroid Build Coastguard Worker if (S->isAtomic())
1096*9880d681SAndroid Build Coastguard Worker return false;
1097*9880d681SAndroid Build Coastguard Worker
1098*9880d681SAndroid Build Coastguard Worker const Value *PtrV = I->getOperand(1);
1099*9880d681SAndroid Build Coastguard Worker if (TLI.supportSwiftError()) {
1100*9880d681SAndroid Build Coastguard Worker // Swifterror values can come from either a function parameter with
1101*9880d681SAndroid Build Coastguard Worker // swifterror attribute or an alloca with swifterror attribute.
1102*9880d681SAndroid Build Coastguard Worker if (const Argument *Arg = dyn_cast<Argument>(PtrV)) {
1103*9880d681SAndroid Build Coastguard Worker if (Arg->hasSwiftErrorAttr())
1104*9880d681SAndroid Build Coastguard Worker return false;
1105*9880d681SAndroid Build Coastguard Worker }
1106*9880d681SAndroid Build Coastguard Worker
1107*9880d681SAndroid Build Coastguard Worker if (const AllocaInst *Alloca = dyn_cast<AllocaInst>(PtrV)) {
1108*9880d681SAndroid Build Coastguard Worker if (Alloca->isSwiftError())
1109*9880d681SAndroid Build Coastguard Worker return false;
1110*9880d681SAndroid Build Coastguard Worker }
1111*9880d681SAndroid Build Coastguard Worker }
1112*9880d681SAndroid Build Coastguard Worker
1113*9880d681SAndroid Build Coastguard Worker const Value *Val = S->getValueOperand();
1114*9880d681SAndroid Build Coastguard Worker const Value *Ptr = S->getPointerOperand();
1115*9880d681SAndroid Build Coastguard Worker
1116*9880d681SAndroid Build Coastguard Worker MVT VT;
1117*9880d681SAndroid Build Coastguard Worker if (!isTypeLegal(Val->getType(), VT, /*AllowI1=*/true))
1118*9880d681SAndroid Build Coastguard Worker return false;
1119*9880d681SAndroid Build Coastguard Worker
1120*9880d681SAndroid Build Coastguard Worker unsigned Alignment = S->getAlignment();
1121*9880d681SAndroid Build Coastguard Worker unsigned ABIAlignment = DL.getABITypeAlignment(Val->getType());
1122*9880d681SAndroid Build Coastguard Worker if (Alignment == 0) // Ensure that codegen never sees alignment 0
1123*9880d681SAndroid Build Coastguard Worker Alignment = ABIAlignment;
1124*9880d681SAndroid Build Coastguard Worker bool Aligned = Alignment >= ABIAlignment;
1125*9880d681SAndroid Build Coastguard Worker
1126*9880d681SAndroid Build Coastguard Worker X86AddressMode AM;
1127*9880d681SAndroid Build Coastguard Worker if (!X86SelectAddress(Ptr, AM))
1128*9880d681SAndroid Build Coastguard Worker return false;
1129*9880d681SAndroid Build Coastguard Worker
1130*9880d681SAndroid Build Coastguard Worker return X86FastEmitStore(VT, Val, AM, createMachineMemOperandFor(I), Aligned);
1131*9880d681SAndroid Build Coastguard Worker }
1132*9880d681SAndroid Build Coastguard Worker
1133*9880d681SAndroid Build Coastguard Worker /// X86SelectRet - Select and emit code to implement ret instructions.
X86SelectRet(const Instruction * I)1134*9880d681SAndroid Build Coastguard Worker bool X86FastISel::X86SelectRet(const Instruction *I) {
1135*9880d681SAndroid Build Coastguard Worker const ReturnInst *Ret = cast<ReturnInst>(I);
1136*9880d681SAndroid Build Coastguard Worker const Function &F = *I->getParent()->getParent();
1137*9880d681SAndroid Build Coastguard Worker const X86MachineFunctionInfo *X86MFInfo =
1138*9880d681SAndroid Build Coastguard Worker FuncInfo.MF->getInfo<X86MachineFunctionInfo>();
1139*9880d681SAndroid Build Coastguard Worker
1140*9880d681SAndroid Build Coastguard Worker if (!FuncInfo.CanLowerReturn)
1141*9880d681SAndroid Build Coastguard Worker return false;
1142*9880d681SAndroid Build Coastguard Worker
1143*9880d681SAndroid Build Coastguard Worker if (TLI.supportSwiftError() &&
1144*9880d681SAndroid Build Coastguard Worker F.getAttributes().hasAttrSomewhere(Attribute::SwiftError))
1145*9880d681SAndroid Build Coastguard Worker return false;
1146*9880d681SAndroid Build Coastguard Worker
1147*9880d681SAndroid Build Coastguard Worker if (TLI.supportSplitCSR(FuncInfo.MF))
1148*9880d681SAndroid Build Coastguard Worker return false;
1149*9880d681SAndroid Build Coastguard Worker
1150*9880d681SAndroid Build Coastguard Worker CallingConv::ID CC = F.getCallingConv();
1151*9880d681SAndroid Build Coastguard Worker if (CC != CallingConv::C &&
1152*9880d681SAndroid Build Coastguard Worker CC != CallingConv::Fast &&
1153*9880d681SAndroid Build Coastguard Worker CC != CallingConv::X86_FastCall &&
1154*9880d681SAndroid Build Coastguard Worker CC != CallingConv::X86_StdCall &&
1155*9880d681SAndroid Build Coastguard Worker CC != CallingConv::X86_ThisCall &&
1156*9880d681SAndroid Build Coastguard Worker CC != CallingConv::X86_64_SysV)
1157*9880d681SAndroid Build Coastguard Worker return false;
1158*9880d681SAndroid Build Coastguard Worker
1159*9880d681SAndroid Build Coastguard Worker if (Subtarget->isCallingConvWin64(CC))
1160*9880d681SAndroid Build Coastguard Worker return false;
1161*9880d681SAndroid Build Coastguard Worker
1162*9880d681SAndroid Build Coastguard Worker // Don't handle popping bytes if they don't fit the ret's immediate.
1163*9880d681SAndroid Build Coastguard Worker if (!isUInt<16>(X86MFInfo->getBytesToPopOnReturn()))
1164*9880d681SAndroid Build Coastguard Worker return false;
1165*9880d681SAndroid Build Coastguard Worker
1166*9880d681SAndroid Build Coastguard Worker // fastcc with -tailcallopt is intended to provide a guaranteed
1167*9880d681SAndroid Build Coastguard Worker // tail call optimization. Fastisel doesn't know how to do that.
1168*9880d681SAndroid Build Coastguard Worker if (CC == CallingConv::Fast && TM.Options.GuaranteedTailCallOpt)
1169*9880d681SAndroid Build Coastguard Worker return false;
1170*9880d681SAndroid Build Coastguard Worker
1171*9880d681SAndroid Build Coastguard Worker // Let SDISel handle vararg functions.
1172*9880d681SAndroid Build Coastguard Worker if (F.isVarArg())
1173*9880d681SAndroid Build Coastguard Worker return false;
1174*9880d681SAndroid Build Coastguard Worker
1175*9880d681SAndroid Build Coastguard Worker // Build a list of return value registers.
1176*9880d681SAndroid Build Coastguard Worker SmallVector<unsigned, 4> RetRegs;
1177*9880d681SAndroid Build Coastguard Worker
1178*9880d681SAndroid Build Coastguard Worker if (Ret->getNumOperands() > 0) {
1179*9880d681SAndroid Build Coastguard Worker SmallVector<ISD::OutputArg, 4> Outs;
1180*9880d681SAndroid Build Coastguard Worker GetReturnInfo(F.getReturnType(), F.getAttributes(), Outs, TLI, DL);
1181*9880d681SAndroid Build Coastguard Worker
1182*9880d681SAndroid Build Coastguard Worker // Analyze operands of the call, assigning locations to each operand.
1183*9880d681SAndroid Build Coastguard Worker SmallVector<CCValAssign, 16> ValLocs;
1184*9880d681SAndroid Build Coastguard Worker CCState CCInfo(CC, F.isVarArg(), *FuncInfo.MF, ValLocs, I->getContext());
1185*9880d681SAndroid Build Coastguard Worker CCInfo.AnalyzeReturn(Outs, RetCC_X86);
1186*9880d681SAndroid Build Coastguard Worker
1187*9880d681SAndroid Build Coastguard Worker const Value *RV = Ret->getOperand(0);
1188*9880d681SAndroid Build Coastguard Worker unsigned Reg = getRegForValue(RV);
1189*9880d681SAndroid Build Coastguard Worker if (Reg == 0)
1190*9880d681SAndroid Build Coastguard Worker return false;
1191*9880d681SAndroid Build Coastguard Worker
1192*9880d681SAndroid Build Coastguard Worker // Only handle a single return value for now.
1193*9880d681SAndroid Build Coastguard Worker if (ValLocs.size() != 1)
1194*9880d681SAndroid Build Coastguard Worker return false;
1195*9880d681SAndroid Build Coastguard Worker
1196*9880d681SAndroid Build Coastguard Worker CCValAssign &VA = ValLocs[0];
1197*9880d681SAndroid Build Coastguard Worker
1198*9880d681SAndroid Build Coastguard Worker // Don't bother handling odd stuff for now.
1199*9880d681SAndroid Build Coastguard Worker if (VA.getLocInfo() != CCValAssign::Full)
1200*9880d681SAndroid Build Coastguard Worker return false;
1201*9880d681SAndroid Build Coastguard Worker // Only handle register returns for now.
1202*9880d681SAndroid Build Coastguard Worker if (!VA.isRegLoc())
1203*9880d681SAndroid Build Coastguard Worker return false;
1204*9880d681SAndroid Build Coastguard Worker
1205*9880d681SAndroid Build Coastguard Worker // The calling-convention tables for x87 returns don't tell
1206*9880d681SAndroid Build Coastguard Worker // the whole story.
1207*9880d681SAndroid Build Coastguard Worker if (VA.getLocReg() == X86::FP0 || VA.getLocReg() == X86::FP1)
1208*9880d681SAndroid Build Coastguard Worker return false;
1209*9880d681SAndroid Build Coastguard Worker
1210*9880d681SAndroid Build Coastguard Worker unsigned SrcReg = Reg + VA.getValNo();
1211*9880d681SAndroid Build Coastguard Worker EVT SrcVT = TLI.getValueType(DL, RV->getType());
1212*9880d681SAndroid Build Coastguard Worker EVT DstVT = VA.getValVT();
1213*9880d681SAndroid Build Coastguard Worker // Special handling for extended integers.
1214*9880d681SAndroid Build Coastguard Worker if (SrcVT != DstVT) {
1215*9880d681SAndroid Build Coastguard Worker if (SrcVT != MVT::i1 && SrcVT != MVT::i8 && SrcVT != MVT::i16)
1216*9880d681SAndroid Build Coastguard Worker return false;
1217*9880d681SAndroid Build Coastguard Worker
1218*9880d681SAndroid Build Coastguard Worker if (!Outs[0].Flags.isZExt() && !Outs[0].Flags.isSExt())
1219*9880d681SAndroid Build Coastguard Worker return false;
1220*9880d681SAndroid Build Coastguard Worker
1221*9880d681SAndroid Build Coastguard Worker assert(DstVT == MVT::i32 && "X86 should always ext to i32");
1222*9880d681SAndroid Build Coastguard Worker
1223*9880d681SAndroid Build Coastguard Worker if (SrcVT == MVT::i1) {
1224*9880d681SAndroid Build Coastguard Worker if (Outs[0].Flags.isSExt())
1225*9880d681SAndroid Build Coastguard Worker return false;
1226*9880d681SAndroid Build Coastguard Worker SrcReg = fastEmitZExtFromI1(MVT::i8, SrcReg, /*TODO: Kill=*/false);
1227*9880d681SAndroid Build Coastguard Worker SrcVT = MVT::i8;
1228*9880d681SAndroid Build Coastguard Worker }
1229*9880d681SAndroid Build Coastguard Worker unsigned Op = Outs[0].Flags.isZExt() ? ISD::ZERO_EXTEND :
1230*9880d681SAndroid Build Coastguard Worker ISD::SIGN_EXTEND;
1231*9880d681SAndroid Build Coastguard Worker SrcReg = fastEmit_r(SrcVT.getSimpleVT(), DstVT.getSimpleVT(), Op,
1232*9880d681SAndroid Build Coastguard Worker SrcReg, /*TODO: Kill=*/false);
1233*9880d681SAndroid Build Coastguard Worker }
1234*9880d681SAndroid Build Coastguard Worker
1235*9880d681SAndroid Build Coastguard Worker // Make the copy.
1236*9880d681SAndroid Build Coastguard Worker unsigned DstReg = VA.getLocReg();
1237*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *SrcRC = MRI.getRegClass(SrcReg);
1238*9880d681SAndroid Build Coastguard Worker // Avoid a cross-class copy. This is very unlikely.
1239*9880d681SAndroid Build Coastguard Worker if (!SrcRC->contains(DstReg))
1240*9880d681SAndroid Build Coastguard Worker return false;
1241*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1242*9880d681SAndroid Build Coastguard Worker TII.get(TargetOpcode::COPY), DstReg).addReg(SrcReg);
1243*9880d681SAndroid Build Coastguard Worker
1244*9880d681SAndroid Build Coastguard Worker // Add register to return instruction.
1245*9880d681SAndroid Build Coastguard Worker RetRegs.push_back(VA.getLocReg());
1246*9880d681SAndroid Build Coastguard Worker }
1247*9880d681SAndroid Build Coastguard Worker
1248*9880d681SAndroid Build Coastguard Worker // Swift calling convention does not require we copy the sret argument
1249*9880d681SAndroid Build Coastguard Worker // into %rax/%eax for the return, and SRetReturnReg is not set for Swift.
1250*9880d681SAndroid Build Coastguard Worker
1251*9880d681SAndroid Build Coastguard Worker // All x86 ABIs require that for returning structs by value we copy
1252*9880d681SAndroid Build Coastguard Worker // the sret argument into %rax/%eax (depending on ABI) for the return.
1253*9880d681SAndroid Build Coastguard Worker // We saved the argument into a virtual register in the entry block,
1254*9880d681SAndroid Build Coastguard Worker // so now we copy the value out and into %rax/%eax.
1255*9880d681SAndroid Build Coastguard Worker if (F.hasStructRetAttr() && CC != CallingConv::Swift) {
1256*9880d681SAndroid Build Coastguard Worker unsigned Reg = X86MFInfo->getSRetReturnReg();
1257*9880d681SAndroid Build Coastguard Worker assert(Reg &&
1258*9880d681SAndroid Build Coastguard Worker "SRetReturnReg should have been set in LowerFormalArguments()!");
1259*9880d681SAndroid Build Coastguard Worker unsigned RetReg = Subtarget->is64Bit() ? X86::RAX : X86::EAX;
1260*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1261*9880d681SAndroid Build Coastguard Worker TII.get(TargetOpcode::COPY), RetReg).addReg(Reg);
1262*9880d681SAndroid Build Coastguard Worker RetRegs.push_back(RetReg);
1263*9880d681SAndroid Build Coastguard Worker }
1264*9880d681SAndroid Build Coastguard Worker
1265*9880d681SAndroid Build Coastguard Worker // Now emit the RET.
1266*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder MIB;
1267*9880d681SAndroid Build Coastguard Worker if (X86MFInfo->getBytesToPopOnReturn()) {
1268*9880d681SAndroid Build Coastguard Worker MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1269*9880d681SAndroid Build Coastguard Worker TII.get(Subtarget->is64Bit() ? X86::RETIQ : X86::RETIL))
1270*9880d681SAndroid Build Coastguard Worker .addImm(X86MFInfo->getBytesToPopOnReturn());
1271*9880d681SAndroid Build Coastguard Worker } else {
1272*9880d681SAndroid Build Coastguard Worker MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1273*9880d681SAndroid Build Coastguard Worker TII.get(Subtarget->is64Bit() ? X86::RETQ : X86::RETL));
1274*9880d681SAndroid Build Coastguard Worker }
1275*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = RetRegs.size(); i != e; ++i)
1276*9880d681SAndroid Build Coastguard Worker MIB.addReg(RetRegs[i], RegState::Implicit);
1277*9880d681SAndroid Build Coastguard Worker return true;
1278*9880d681SAndroid Build Coastguard Worker }
1279*9880d681SAndroid Build Coastguard Worker
1280*9880d681SAndroid Build Coastguard Worker /// X86SelectLoad - Select and emit code to implement load instructions.
1281*9880d681SAndroid Build Coastguard Worker ///
X86SelectLoad(const Instruction * I)1282*9880d681SAndroid Build Coastguard Worker bool X86FastISel::X86SelectLoad(const Instruction *I) {
1283*9880d681SAndroid Build Coastguard Worker const LoadInst *LI = cast<LoadInst>(I);
1284*9880d681SAndroid Build Coastguard Worker
1285*9880d681SAndroid Build Coastguard Worker // Atomic loads need special handling.
1286*9880d681SAndroid Build Coastguard Worker if (LI->isAtomic())
1287*9880d681SAndroid Build Coastguard Worker return false;
1288*9880d681SAndroid Build Coastguard Worker
1289*9880d681SAndroid Build Coastguard Worker const Value *SV = I->getOperand(0);
1290*9880d681SAndroid Build Coastguard Worker if (TLI.supportSwiftError()) {
1291*9880d681SAndroid Build Coastguard Worker // Swifterror values can come from either a function parameter with
1292*9880d681SAndroid Build Coastguard Worker // swifterror attribute or an alloca with swifterror attribute.
1293*9880d681SAndroid Build Coastguard Worker if (const Argument *Arg = dyn_cast<Argument>(SV)) {
1294*9880d681SAndroid Build Coastguard Worker if (Arg->hasSwiftErrorAttr())
1295*9880d681SAndroid Build Coastguard Worker return false;
1296*9880d681SAndroid Build Coastguard Worker }
1297*9880d681SAndroid Build Coastguard Worker
1298*9880d681SAndroid Build Coastguard Worker if (const AllocaInst *Alloca = dyn_cast<AllocaInst>(SV)) {
1299*9880d681SAndroid Build Coastguard Worker if (Alloca->isSwiftError())
1300*9880d681SAndroid Build Coastguard Worker return false;
1301*9880d681SAndroid Build Coastguard Worker }
1302*9880d681SAndroid Build Coastguard Worker }
1303*9880d681SAndroid Build Coastguard Worker
1304*9880d681SAndroid Build Coastguard Worker MVT VT;
1305*9880d681SAndroid Build Coastguard Worker if (!isTypeLegal(LI->getType(), VT, /*AllowI1=*/true))
1306*9880d681SAndroid Build Coastguard Worker return false;
1307*9880d681SAndroid Build Coastguard Worker
1308*9880d681SAndroid Build Coastguard Worker const Value *Ptr = LI->getPointerOperand();
1309*9880d681SAndroid Build Coastguard Worker
1310*9880d681SAndroid Build Coastguard Worker X86AddressMode AM;
1311*9880d681SAndroid Build Coastguard Worker if (!X86SelectAddress(Ptr, AM))
1312*9880d681SAndroid Build Coastguard Worker return false;
1313*9880d681SAndroid Build Coastguard Worker
1314*9880d681SAndroid Build Coastguard Worker unsigned Alignment = LI->getAlignment();
1315*9880d681SAndroid Build Coastguard Worker unsigned ABIAlignment = DL.getABITypeAlignment(LI->getType());
1316*9880d681SAndroid Build Coastguard Worker if (Alignment == 0) // Ensure that codegen never sees alignment 0
1317*9880d681SAndroid Build Coastguard Worker Alignment = ABIAlignment;
1318*9880d681SAndroid Build Coastguard Worker
1319*9880d681SAndroid Build Coastguard Worker unsigned ResultReg = 0;
1320*9880d681SAndroid Build Coastguard Worker if (!X86FastEmitLoad(VT, AM, createMachineMemOperandFor(LI), ResultReg,
1321*9880d681SAndroid Build Coastguard Worker Alignment))
1322*9880d681SAndroid Build Coastguard Worker return false;
1323*9880d681SAndroid Build Coastguard Worker
1324*9880d681SAndroid Build Coastguard Worker updateValueMap(I, ResultReg);
1325*9880d681SAndroid Build Coastguard Worker return true;
1326*9880d681SAndroid Build Coastguard Worker }
1327*9880d681SAndroid Build Coastguard Worker
X86ChooseCmpOpcode(EVT VT,const X86Subtarget * Subtarget)1328*9880d681SAndroid Build Coastguard Worker static unsigned X86ChooseCmpOpcode(EVT VT, const X86Subtarget *Subtarget) {
1329*9880d681SAndroid Build Coastguard Worker bool HasAVX = Subtarget->hasAVX();
1330*9880d681SAndroid Build Coastguard Worker bool X86ScalarSSEf32 = Subtarget->hasSSE1();
1331*9880d681SAndroid Build Coastguard Worker bool X86ScalarSSEf64 = Subtarget->hasSSE2();
1332*9880d681SAndroid Build Coastguard Worker
1333*9880d681SAndroid Build Coastguard Worker switch (VT.getSimpleVT().SimpleTy) {
1334*9880d681SAndroid Build Coastguard Worker default: return 0;
1335*9880d681SAndroid Build Coastguard Worker case MVT::i8: return X86::CMP8rr;
1336*9880d681SAndroid Build Coastguard Worker case MVT::i16: return X86::CMP16rr;
1337*9880d681SAndroid Build Coastguard Worker case MVT::i32: return X86::CMP32rr;
1338*9880d681SAndroid Build Coastguard Worker case MVT::i64: return X86::CMP64rr;
1339*9880d681SAndroid Build Coastguard Worker case MVT::f32:
1340*9880d681SAndroid Build Coastguard Worker return X86ScalarSSEf32 ? (HasAVX ? X86::VUCOMISSrr : X86::UCOMISSrr) : 0;
1341*9880d681SAndroid Build Coastguard Worker case MVT::f64:
1342*9880d681SAndroid Build Coastguard Worker return X86ScalarSSEf64 ? (HasAVX ? X86::VUCOMISDrr : X86::UCOMISDrr) : 0;
1343*9880d681SAndroid Build Coastguard Worker }
1344*9880d681SAndroid Build Coastguard Worker }
1345*9880d681SAndroid Build Coastguard Worker
1346*9880d681SAndroid Build Coastguard Worker /// If we have a comparison with RHS as the RHS of the comparison, return an
1347*9880d681SAndroid Build Coastguard Worker /// opcode that works for the compare (e.g. CMP32ri) otherwise return 0.
X86ChooseCmpImmediateOpcode(EVT VT,const ConstantInt * RHSC)1348*9880d681SAndroid Build Coastguard Worker static unsigned X86ChooseCmpImmediateOpcode(EVT VT, const ConstantInt *RHSC) {
1349*9880d681SAndroid Build Coastguard Worker int64_t Val = RHSC->getSExtValue();
1350*9880d681SAndroid Build Coastguard Worker switch (VT.getSimpleVT().SimpleTy) {
1351*9880d681SAndroid Build Coastguard Worker // Otherwise, we can't fold the immediate into this comparison.
1352*9880d681SAndroid Build Coastguard Worker default:
1353*9880d681SAndroid Build Coastguard Worker return 0;
1354*9880d681SAndroid Build Coastguard Worker case MVT::i8:
1355*9880d681SAndroid Build Coastguard Worker return X86::CMP8ri;
1356*9880d681SAndroid Build Coastguard Worker case MVT::i16:
1357*9880d681SAndroid Build Coastguard Worker if (isInt<8>(Val))
1358*9880d681SAndroid Build Coastguard Worker return X86::CMP16ri8;
1359*9880d681SAndroid Build Coastguard Worker return X86::CMP16ri;
1360*9880d681SAndroid Build Coastguard Worker case MVT::i32:
1361*9880d681SAndroid Build Coastguard Worker if (isInt<8>(Val))
1362*9880d681SAndroid Build Coastguard Worker return X86::CMP32ri8;
1363*9880d681SAndroid Build Coastguard Worker return X86::CMP32ri;
1364*9880d681SAndroid Build Coastguard Worker case MVT::i64:
1365*9880d681SAndroid Build Coastguard Worker if (isInt<8>(Val))
1366*9880d681SAndroid Build Coastguard Worker return X86::CMP64ri8;
1367*9880d681SAndroid Build Coastguard Worker // 64-bit comparisons are only valid if the immediate fits in a 32-bit sext
1368*9880d681SAndroid Build Coastguard Worker // field.
1369*9880d681SAndroid Build Coastguard Worker if (isInt<32>(Val))
1370*9880d681SAndroid Build Coastguard Worker return X86::CMP64ri32;
1371*9880d681SAndroid Build Coastguard Worker return 0;
1372*9880d681SAndroid Build Coastguard Worker }
1373*9880d681SAndroid Build Coastguard Worker }
1374*9880d681SAndroid Build Coastguard Worker
X86FastEmitCompare(const Value * Op0,const Value * Op1,EVT VT,const DebugLoc & CurDbgLoc)1375*9880d681SAndroid Build Coastguard Worker bool X86FastISel::X86FastEmitCompare(const Value *Op0, const Value *Op1, EVT VT,
1376*9880d681SAndroid Build Coastguard Worker const DebugLoc &CurDbgLoc) {
1377*9880d681SAndroid Build Coastguard Worker unsigned Op0Reg = getRegForValue(Op0);
1378*9880d681SAndroid Build Coastguard Worker if (Op0Reg == 0) return false;
1379*9880d681SAndroid Build Coastguard Worker
1380*9880d681SAndroid Build Coastguard Worker // Handle 'null' like i32/i64 0.
1381*9880d681SAndroid Build Coastguard Worker if (isa<ConstantPointerNull>(Op1))
1382*9880d681SAndroid Build Coastguard Worker Op1 = Constant::getNullValue(DL.getIntPtrType(Op0->getContext()));
1383*9880d681SAndroid Build Coastguard Worker
1384*9880d681SAndroid Build Coastguard Worker // We have two options: compare with register or immediate. If the RHS of
1385*9880d681SAndroid Build Coastguard Worker // the compare is an immediate that we can fold into this compare, use
1386*9880d681SAndroid Build Coastguard Worker // CMPri, otherwise use CMPrr.
1387*9880d681SAndroid Build Coastguard Worker if (const ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) {
1388*9880d681SAndroid Build Coastguard Worker if (unsigned CompareImmOpc = X86ChooseCmpImmediateOpcode(VT, Op1C)) {
1389*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, CurDbgLoc, TII.get(CompareImmOpc))
1390*9880d681SAndroid Build Coastguard Worker .addReg(Op0Reg)
1391*9880d681SAndroid Build Coastguard Worker .addImm(Op1C->getSExtValue());
1392*9880d681SAndroid Build Coastguard Worker return true;
1393*9880d681SAndroid Build Coastguard Worker }
1394*9880d681SAndroid Build Coastguard Worker }
1395*9880d681SAndroid Build Coastguard Worker
1396*9880d681SAndroid Build Coastguard Worker unsigned CompareOpc = X86ChooseCmpOpcode(VT, Subtarget);
1397*9880d681SAndroid Build Coastguard Worker if (CompareOpc == 0) return false;
1398*9880d681SAndroid Build Coastguard Worker
1399*9880d681SAndroid Build Coastguard Worker unsigned Op1Reg = getRegForValue(Op1);
1400*9880d681SAndroid Build Coastguard Worker if (Op1Reg == 0) return false;
1401*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, CurDbgLoc, TII.get(CompareOpc))
1402*9880d681SAndroid Build Coastguard Worker .addReg(Op0Reg)
1403*9880d681SAndroid Build Coastguard Worker .addReg(Op1Reg);
1404*9880d681SAndroid Build Coastguard Worker
1405*9880d681SAndroid Build Coastguard Worker return true;
1406*9880d681SAndroid Build Coastguard Worker }
1407*9880d681SAndroid Build Coastguard Worker
X86SelectCmp(const Instruction * I)1408*9880d681SAndroid Build Coastguard Worker bool X86FastISel::X86SelectCmp(const Instruction *I) {
1409*9880d681SAndroid Build Coastguard Worker const CmpInst *CI = cast<CmpInst>(I);
1410*9880d681SAndroid Build Coastguard Worker
1411*9880d681SAndroid Build Coastguard Worker MVT VT;
1412*9880d681SAndroid Build Coastguard Worker if (!isTypeLegal(I->getOperand(0)->getType(), VT))
1413*9880d681SAndroid Build Coastguard Worker return false;
1414*9880d681SAndroid Build Coastguard Worker
1415*9880d681SAndroid Build Coastguard Worker if (I->getType()->isIntegerTy(1) && Subtarget->hasAVX512())
1416*9880d681SAndroid Build Coastguard Worker return false;
1417*9880d681SAndroid Build Coastguard Worker
1418*9880d681SAndroid Build Coastguard Worker // Try to optimize or fold the cmp.
1419*9880d681SAndroid Build Coastguard Worker CmpInst::Predicate Predicate = optimizeCmpPredicate(CI);
1420*9880d681SAndroid Build Coastguard Worker unsigned ResultReg = 0;
1421*9880d681SAndroid Build Coastguard Worker switch (Predicate) {
1422*9880d681SAndroid Build Coastguard Worker default: break;
1423*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_FALSE: {
1424*9880d681SAndroid Build Coastguard Worker ResultReg = createResultReg(&X86::GR32RegClass);
1425*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::MOV32r0),
1426*9880d681SAndroid Build Coastguard Worker ResultReg);
1427*9880d681SAndroid Build Coastguard Worker ResultReg = fastEmitInst_extractsubreg(MVT::i8, ResultReg, /*Kill=*/true,
1428*9880d681SAndroid Build Coastguard Worker X86::sub_8bit);
1429*9880d681SAndroid Build Coastguard Worker if (!ResultReg)
1430*9880d681SAndroid Build Coastguard Worker return false;
1431*9880d681SAndroid Build Coastguard Worker break;
1432*9880d681SAndroid Build Coastguard Worker }
1433*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_TRUE: {
1434*9880d681SAndroid Build Coastguard Worker ResultReg = createResultReg(&X86::GR8RegClass);
1435*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::MOV8ri),
1436*9880d681SAndroid Build Coastguard Worker ResultReg).addImm(1);
1437*9880d681SAndroid Build Coastguard Worker break;
1438*9880d681SAndroid Build Coastguard Worker }
1439*9880d681SAndroid Build Coastguard Worker }
1440*9880d681SAndroid Build Coastguard Worker
1441*9880d681SAndroid Build Coastguard Worker if (ResultReg) {
1442*9880d681SAndroid Build Coastguard Worker updateValueMap(I, ResultReg);
1443*9880d681SAndroid Build Coastguard Worker return true;
1444*9880d681SAndroid Build Coastguard Worker }
1445*9880d681SAndroid Build Coastguard Worker
1446*9880d681SAndroid Build Coastguard Worker const Value *LHS = CI->getOperand(0);
1447*9880d681SAndroid Build Coastguard Worker const Value *RHS = CI->getOperand(1);
1448*9880d681SAndroid Build Coastguard Worker
1449*9880d681SAndroid Build Coastguard Worker // The optimizer might have replaced fcmp oeq %x, %x with fcmp ord %x, 0.0.
1450*9880d681SAndroid Build Coastguard Worker // We don't have to materialize a zero constant for this case and can just use
1451*9880d681SAndroid Build Coastguard Worker // %x again on the RHS.
1452*9880d681SAndroid Build Coastguard Worker if (Predicate == CmpInst::FCMP_ORD || Predicate == CmpInst::FCMP_UNO) {
1453*9880d681SAndroid Build Coastguard Worker const auto *RHSC = dyn_cast<ConstantFP>(RHS);
1454*9880d681SAndroid Build Coastguard Worker if (RHSC && RHSC->isNullValue())
1455*9880d681SAndroid Build Coastguard Worker RHS = LHS;
1456*9880d681SAndroid Build Coastguard Worker }
1457*9880d681SAndroid Build Coastguard Worker
1458*9880d681SAndroid Build Coastguard Worker // FCMP_OEQ and FCMP_UNE cannot be checked with a single instruction.
1459*9880d681SAndroid Build Coastguard Worker static unsigned SETFOpcTable[2][3] = {
1460*9880d681SAndroid Build Coastguard Worker { X86::SETEr, X86::SETNPr, X86::AND8rr },
1461*9880d681SAndroid Build Coastguard Worker { X86::SETNEr, X86::SETPr, X86::OR8rr }
1462*9880d681SAndroid Build Coastguard Worker };
1463*9880d681SAndroid Build Coastguard Worker unsigned *SETFOpc = nullptr;
1464*9880d681SAndroid Build Coastguard Worker switch (Predicate) {
1465*9880d681SAndroid Build Coastguard Worker default: break;
1466*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_OEQ: SETFOpc = &SETFOpcTable[0][0]; break;
1467*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_UNE: SETFOpc = &SETFOpcTable[1][0]; break;
1468*9880d681SAndroid Build Coastguard Worker }
1469*9880d681SAndroid Build Coastguard Worker
1470*9880d681SAndroid Build Coastguard Worker ResultReg = createResultReg(&X86::GR8RegClass);
1471*9880d681SAndroid Build Coastguard Worker if (SETFOpc) {
1472*9880d681SAndroid Build Coastguard Worker if (!X86FastEmitCompare(LHS, RHS, VT, I->getDebugLoc()))
1473*9880d681SAndroid Build Coastguard Worker return false;
1474*9880d681SAndroid Build Coastguard Worker
1475*9880d681SAndroid Build Coastguard Worker unsigned FlagReg1 = createResultReg(&X86::GR8RegClass);
1476*9880d681SAndroid Build Coastguard Worker unsigned FlagReg2 = createResultReg(&X86::GR8RegClass);
1477*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(SETFOpc[0]),
1478*9880d681SAndroid Build Coastguard Worker FlagReg1);
1479*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(SETFOpc[1]),
1480*9880d681SAndroid Build Coastguard Worker FlagReg2);
1481*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(SETFOpc[2]),
1482*9880d681SAndroid Build Coastguard Worker ResultReg).addReg(FlagReg1).addReg(FlagReg2);
1483*9880d681SAndroid Build Coastguard Worker updateValueMap(I, ResultReg);
1484*9880d681SAndroid Build Coastguard Worker return true;
1485*9880d681SAndroid Build Coastguard Worker }
1486*9880d681SAndroid Build Coastguard Worker
1487*9880d681SAndroid Build Coastguard Worker X86::CondCode CC;
1488*9880d681SAndroid Build Coastguard Worker bool SwapArgs;
1489*9880d681SAndroid Build Coastguard Worker std::tie(CC, SwapArgs) = getX86ConditionCode(Predicate);
1490*9880d681SAndroid Build Coastguard Worker assert(CC <= X86::LAST_VALID_COND && "Unexpected condition code.");
1491*9880d681SAndroid Build Coastguard Worker unsigned Opc = X86::getSETFromCond(CC);
1492*9880d681SAndroid Build Coastguard Worker
1493*9880d681SAndroid Build Coastguard Worker if (SwapArgs)
1494*9880d681SAndroid Build Coastguard Worker std::swap(LHS, RHS);
1495*9880d681SAndroid Build Coastguard Worker
1496*9880d681SAndroid Build Coastguard Worker // Emit a compare of LHS/RHS.
1497*9880d681SAndroid Build Coastguard Worker if (!X86FastEmitCompare(LHS, RHS, VT, I->getDebugLoc()))
1498*9880d681SAndroid Build Coastguard Worker return false;
1499*9880d681SAndroid Build Coastguard Worker
1500*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg);
1501*9880d681SAndroid Build Coastguard Worker updateValueMap(I, ResultReg);
1502*9880d681SAndroid Build Coastguard Worker return true;
1503*9880d681SAndroid Build Coastguard Worker }
1504*9880d681SAndroid Build Coastguard Worker
X86SelectZExt(const Instruction * I)1505*9880d681SAndroid Build Coastguard Worker bool X86FastISel::X86SelectZExt(const Instruction *I) {
1506*9880d681SAndroid Build Coastguard Worker EVT DstVT = TLI.getValueType(DL, I->getType());
1507*9880d681SAndroid Build Coastguard Worker if (!TLI.isTypeLegal(DstVT))
1508*9880d681SAndroid Build Coastguard Worker return false;
1509*9880d681SAndroid Build Coastguard Worker
1510*9880d681SAndroid Build Coastguard Worker unsigned ResultReg = getRegForValue(I->getOperand(0));
1511*9880d681SAndroid Build Coastguard Worker if (ResultReg == 0)
1512*9880d681SAndroid Build Coastguard Worker return false;
1513*9880d681SAndroid Build Coastguard Worker
1514*9880d681SAndroid Build Coastguard Worker // Handle zero-extension from i1 to i8, which is common.
1515*9880d681SAndroid Build Coastguard Worker MVT SrcVT = TLI.getSimpleValueType(DL, I->getOperand(0)->getType());
1516*9880d681SAndroid Build Coastguard Worker if (SrcVT.SimpleTy == MVT::i1) {
1517*9880d681SAndroid Build Coastguard Worker // Set the high bits to zero.
1518*9880d681SAndroid Build Coastguard Worker ResultReg = fastEmitZExtFromI1(MVT::i8, ResultReg, /*TODO: Kill=*/false);
1519*9880d681SAndroid Build Coastguard Worker SrcVT = MVT::i8;
1520*9880d681SAndroid Build Coastguard Worker
1521*9880d681SAndroid Build Coastguard Worker if (ResultReg == 0)
1522*9880d681SAndroid Build Coastguard Worker return false;
1523*9880d681SAndroid Build Coastguard Worker }
1524*9880d681SAndroid Build Coastguard Worker
1525*9880d681SAndroid Build Coastguard Worker if (DstVT == MVT::i64) {
1526*9880d681SAndroid Build Coastguard Worker // Handle extension to 64-bits via sub-register shenanigans.
1527*9880d681SAndroid Build Coastguard Worker unsigned MovInst;
1528*9880d681SAndroid Build Coastguard Worker
1529*9880d681SAndroid Build Coastguard Worker switch (SrcVT.SimpleTy) {
1530*9880d681SAndroid Build Coastguard Worker case MVT::i8: MovInst = X86::MOVZX32rr8; break;
1531*9880d681SAndroid Build Coastguard Worker case MVT::i16: MovInst = X86::MOVZX32rr16; break;
1532*9880d681SAndroid Build Coastguard Worker case MVT::i32: MovInst = X86::MOV32rr; break;
1533*9880d681SAndroid Build Coastguard Worker default: llvm_unreachable("Unexpected zext to i64 source type");
1534*9880d681SAndroid Build Coastguard Worker }
1535*9880d681SAndroid Build Coastguard Worker
1536*9880d681SAndroid Build Coastguard Worker unsigned Result32 = createResultReg(&X86::GR32RegClass);
1537*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(MovInst), Result32)
1538*9880d681SAndroid Build Coastguard Worker .addReg(ResultReg);
1539*9880d681SAndroid Build Coastguard Worker
1540*9880d681SAndroid Build Coastguard Worker ResultReg = createResultReg(&X86::GR64RegClass);
1541*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(TargetOpcode::SUBREG_TO_REG),
1542*9880d681SAndroid Build Coastguard Worker ResultReg)
1543*9880d681SAndroid Build Coastguard Worker .addImm(0).addReg(Result32).addImm(X86::sub_32bit);
1544*9880d681SAndroid Build Coastguard Worker } else if (DstVT != MVT::i8) {
1545*9880d681SAndroid Build Coastguard Worker ResultReg = fastEmit_r(MVT::i8, DstVT.getSimpleVT(), ISD::ZERO_EXTEND,
1546*9880d681SAndroid Build Coastguard Worker ResultReg, /*Kill=*/true);
1547*9880d681SAndroid Build Coastguard Worker if (ResultReg == 0)
1548*9880d681SAndroid Build Coastguard Worker return false;
1549*9880d681SAndroid Build Coastguard Worker }
1550*9880d681SAndroid Build Coastguard Worker
1551*9880d681SAndroid Build Coastguard Worker updateValueMap(I, ResultReg);
1552*9880d681SAndroid Build Coastguard Worker return true;
1553*9880d681SAndroid Build Coastguard Worker }
1554*9880d681SAndroid Build Coastguard Worker
X86SelectBranch(const Instruction * I)1555*9880d681SAndroid Build Coastguard Worker bool X86FastISel::X86SelectBranch(const Instruction *I) {
1556*9880d681SAndroid Build Coastguard Worker // Unconditional branches are selected by tablegen-generated code.
1557*9880d681SAndroid Build Coastguard Worker // Handle a conditional branch.
1558*9880d681SAndroid Build Coastguard Worker const BranchInst *BI = cast<BranchInst>(I);
1559*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *TrueMBB = FuncInfo.MBBMap[BI->getSuccessor(0)];
1560*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *FalseMBB = FuncInfo.MBBMap[BI->getSuccessor(1)];
1561*9880d681SAndroid Build Coastguard Worker
1562*9880d681SAndroid Build Coastguard Worker // Fold the common case of a conditional branch with a comparison
1563*9880d681SAndroid Build Coastguard Worker // in the same block (values defined on other blocks may not have
1564*9880d681SAndroid Build Coastguard Worker // initialized registers).
1565*9880d681SAndroid Build Coastguard Worker X86::CondCode CC;
1566*9880d681SAndroid Build Coastguard Worker if (const CmpInst *CI = dyn_cast<CmpInst>(BI->getCondition())) {
1567*9880d681SAndroid Build Coastguard Worker if (CI->hasOneUse() && CI->getParent() == I->getParent()) {
1568*9880d681SAndroid Build Coastguard Worker EVT VT = TLI.getValueType(DL, CI->getOperand(0)->getType());
1569*9880d681SAndroid Build Coastguard Worker
1570*9880d681SAndroid Build Coastguard Worker // Try to optimize or fold the cmp.
1571*9880d681SAndroid Build Coastguard Worker CmpInst::Predicate Predicate = optimizeCmpPredicate(CI);
1572*9880d681SAndroid Build Coastguard Worker switch (Predicate) {
1573*9880d681SAndroid Build Coastguard Worker default: break;
1574*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_FALSE: fastEmitBranch(FalseMBB, DbgLoc); return true;
1575*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_TRUE: fastEmitBranch(TrueMBB, DbgLoc); return true;
1576*9880d681SAndroid Build Coastguard Worker }
1577*9880d681SAndroid Build Coastguard Worker
1578*9880d681SAndroid Build Coastguard Worker const Value *CmpLHS = CI->getOperand(0);
1579*9880d681SAndroid Build Coastguard Worker const Value *CmpRHS = CI->getOperand(1);
1580*9880d681SAndroid Build Coastguard Worker
1581*9880d681SAndroid Build Coastguard Worker // The optimizer might have replaced fcmp oeq %x, %x with fcmp ord %x,
1582*9880d681SAndroid Build Coastguard Worker // 0.0.
1583*9880d681SAndroid Build Coastguard Worker // We don't have to materialize a zero constant for this case and can just
1584*9880d681SAndroid Build Coastguard Worker // use %x again on the RHS.
1585*9880d681SAndroid Build Coastguard Worker if (Predicate == CmpInst::FCMP_ORD || Predicate == CmpInst::FCMP_UNO) {
1586*9880d681SAndroid Build Coastguard Worker const auto *CmpRHSC = dyn_cast<ConstantFP>(CmpRHS);
1587*9880d681SAndroid Build Coastguard Worker if (CmpRHSC && CmpRHSC->isNullValue())
1588*9880d681SAndroid Build Coastguard Worker CmpRHS = CmpLHS;
1589*9880d681SAndroid Build Coastguard Worker }
1590*9880d681SAndroid Build Coastguard Worker
1591*9880d681SAndroid Build Coastguard Worker // Try to take advantage of fallthrough opportunities.
1592*9880d681SAndroid Build Coastguard Worker if (FuncInfo.MBB->isLayoutSuccessor(TrueMBB)) {
1593*9880d681SAndroid Build Coastguard Worker std::swap(TrueMBB, FalseMBB);
1594*9880d681SAndroid Build Coastguard Worker Predicate = CmpInst::getInversePredicate(Predicate);
1595*9880d681SAndroid Build Coastguard Worker }
1596*9880d681SAndroid Build Coastguard Worker
1597*9880d681SAndroid Build Coastguard Worker // FCMP_OEQ and FCMP_UNE cannot be expressed with a single flag/condition
1598*9880d681SAndroid Build Coastguard Worker // code check. Instead two branch instructions are required to check all
1599*9880d681SAndroid Build Coastguard Worker // the flags. First we change the predicate to a supported condition code,
1600*9880d681SAndroid Build Coastguard Worker // which will be the first branch. Later one we will emit the second
1601*9880d681SAndroid Build Coastguard Worker // branch.
1602*9880d681SAndroid Build Coastguard Worker bool NeedExtraBranch = false;
1603*9880d681SAndroid Build Coastguard Worker switch (Predicate) {
1604*9880d681SAndroid Build Coastguard Worker default: break;
1605*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_OEQ:
1606*9880d681SAndroid Build Coastguard Worker std::swap(TrueMBB, FalseMBB); // fall-through
1607*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_UNE:
1608*9880d681SAndroid Build Coastguard Worker NeedExtraBranch = true;
1609*9880d681SAndroid Build Coastguard Worker Predicate = CmpInst::FCMP_ONE;
1610*9880d681SAndroid Build Coastguard Worker break;
1611*9880d681SAndroid Build Coastguard Worker }
1612*9880d681SAndroid Build Coastguard Worker
1613*9880d681SAndroid Build Coastguard Worker bool SwapArgs;
1614*9880d681SAndroid Build Coastguard Worker unsigned BranchOpc;
1615*9880d681SAndroid Build Coastguard Worker std::tie(CC, SwapArgs) = getX86ConditionCode(Predicate);
1616*9880d681SAndroid Build Coastguard Worker assert(CC <= X86::LAST_VALID_COND && "Unexpected condition code.");
1617*9880d681SAndroid Build Coastguard Worker
1618*9880d681SAndroid Build Coastguard Worker BranchOpc = X86::GetCondBranchFromCond(CC);
1619*9880d681SAndroid Build Coastguard Worker if (SwapArgs)
1620*9880d681SAndroid Build Coastguard Worker std::swap(CmpLHS, CmpRHS);
1621*9880d681SAndroid Build Coastguard Worker
1622*9880d681SAndroid Build Coastguard Worker // Emit a compare of the LHS and RHS, setting the flags.
1623*9880d681SAndroid Build Coastguard Worker if (!X86FastEmitCompare(CmpLHS, CmpRHS, VT, CI->getDebugLoc()))
1624*9880d681SAndroid Build Coastguard Worker return false;
1625*9880d681SAndroid Build Coastguard Worker
1626*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(BranchOpc))
1627*9880d681SAndroid Build Coastguard Worker .addMBB(TrueMBB);
1628*9880d681SAndroid Build Coastguard Worker
1629*9880d681SAndroid Build Coastguard Worker // X86 requires a second branch to handle UNE (and OEQ, which is mapped
1630*9880d681SAndroid Build Coastguard Worker // to UNE above).
1631*9880d681SAndroid Build Coastguard Worker if (NeedExtraBranch) {
1632*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::JP_1))
1633*9880d681SAndroid Build Coastguard Worker .addMBB(TrueMBB);
1634*9880d681SAndroid Build Coastguard Worker }
1635*9880d681SAndroid Build Coastguard Worker
1636*9880d681SAndroid Build Coastguard Worker finishCondBranch(BI->getParent(), TrueMBB, FalseMBB);
1637*9880d681SAndroid Build Coastguard Worker return true;
1638*9880d681SAndroid Build Coastguard Worker }
1639*9880d681SAndroid Build Coastguard Worker } else if (TruncInst *TI = dyn_cast<TruncInst>(BI->getCondition())) {
1640*9880d681SAndroid Build Coastguard Worker // Handle things like "%cond = trunc i32 %X to i1 / br i1 %cond", which
1641*9880d681SAndroid Build Coastguard Worker // typically happen for _Bool and C++ bools.
1642*9880d681SAndroid Build Coastguard Worker MVT SourceVT;
1643*9880d681SAndroid Build Coastguard Worker if (TI->hasOneUse() && TI->getParent() == I->getParent() &&
1644*9880d681SAndroid Build Coastguard Worker isTypeLegal(TI->getOperand(0)->getType(), SourceVT)) {
1645*9880d681SAndroid Build Coastguard Worker unsigned TestOpc = 0;
1646*9880d681SAndroid Build Coastguard Worker switch (SourceVT.SimpleTy) {
1647*9880d681SAndroid Build Coastguard Worker default: break;
1648*9880d681SAndroid Build Coastguard Worker case MVT::i8: TestOpc = X86::TEST8ri; break;
1649*9880d681SAndroid Build Coastguard Worker case MVT::i16: TestOpc = X86::TEST16ri; break;
1650*9880d681SAndroid Build Coastguard Worker case MVT::i32: TestOpc = X86::TEST32ri; break;
1651*9880d681SAndroid Build Coastguard Worker case MVT::i64: TestOpc = X86::TEST64ri32; break;
1652*9880d681SAndroid Build Coastguard Worker }
1653*9880d681SAndroid Build Coastguard Worker if (TestOpc) {
1654*9880d681SAndroid Build Coastguard Worker unsigned OpReg = getRegForValue(TI->getOperand(0));
1655*9880d681SAndroid Build Coastguard Worker if (OpReg == 0) return false;
1656*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(TestOpc))
1657*9880d681SAndroid Build Coastguard Worker .addReg(OpReg).addImm(1);
1658*9880d681SAndroid Build Coastguard Worker
1659*9880d681SAndroid Build Coastguard Worker unsigned JmpOpc = X86::JNE_1;
1660*9880d681SAndroid Build Coastguard Worker if (FuncInfo.MBB->isLayoutSuccessor(TrueMBB)) {
1661*9880d681SAndroid Build Coastguard Worker std::swap(TrueMBB, FalseMBB);
1662*9880d681SAndroid Build Coastguard Worker JmpOpc = X86::JE_1;
1663*9880d681SAndroid Build Coastguard Worker }
1664*9880d681SAndroid Build Coastguard Worker
1665*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(JmpOpc))
1666*9880d681SAndroid Build Coastguard Worker .addMBB(TrueMBB);
1667*9880d681SAndroid Build Coastguard Worker
1668*9880d681SAndroid Build Coastguard Worker finishCondBranch(BI->getParent(), TrueMBB, FalseMBB);
1669*9880d681SAndroid Build Coastguard Worker return true;
1670*9880d681SAndroid Build Coastguard Worker }
1671*9880d681SAndroid Build Coastguard Worker }
1672*9880d681SAndroid Build Coastguard Worker } else if (foldX86XALUIntrinsic(CC, BI, BI->getCondition())) {
1673*9880d681SAndroid Build Coastguard Worker // Fake request the condition, otherwise the intrinsic might be completely
1674*9880d681SAndroid Build Coastguard Worker // optimized away.
1675*9880d681SAndroid Build Coastguard Worker unsigned TmpReg = getRegForValue(BI->getCondition());
1676*9880d681SAndroid Build Coastguard Worker if (TmpReg == 0)
1677*9880d681SAndroid Build Coastguard Worker return false;
1678*9880d681SAndroid Build Coastguard Worker
1679*9880d681SAndroid Build Coastguard Worker unsigned BranchOpc = X86::GetCondBranchFromCond(CC);
1680*9880d681SAndroid Build Coastguard Worker
1681*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(BranchOpc))
1682*9880d681SAndroid Build Coastguard Worker .addMBB(TrueMBB);
1683*9880d681SAndroid Build Coastguard Worker finishCondBranch(BI->getParent(), TrueMBB, FalseMBB);
1684*9880d681SAndroid Build Coastguard Worker return true;
1685*9880d681SAndroid Build Coastguard Worker }
1686*9880d681SAndroid Build Coastguard Worker
1687*9880d681SAndroid Build Coastguard Worker // Otherwise do a clumsy setcc and re-test it.
1688*9880d681SAndroid Build Coastguard Worker // Note that i1 essentially gets ANY_EXTEND'ed to i8 where it isn't used
1689*9880d681SAndroid Build Coastguard Worker // in an explicit cast, so make sure to handle that correctly.
1690*9880d681SAndroid Build Coastguard Worker unsigned OpReg = getRegForValue(BI->getCondition());
1691*9880d681SAndroid Build Coastguard Worker if (OpReg == 0) return false;
1692*9880d681SAndroid Build Coastguard Worker
1693*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::TEST8ri))
1694*9880d681SAndroid Build Coastguard Worker .addReg(OpReg).addImm(1);
1695*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::JNE_1))
1696*9880d681SAndroid Build Coastguard Worker .addMBB(TrueMBB);
1697*9880d681SAndroid Build Coastguard Worker finishCondBranch(BI->getParent(), TrueMBB, FalseMBB);
1698*9880d681SAndroid Build Coastguard Worker return true;
1699*9880d681SAndroid Build Coastguard Worker }
1700*9880d681SAndroid Build Coastguard Worker
X86SelectShift(const Instruction * I)1701*9880d681SAndroid Build Coastguard Worker bool X86FastISel::X86SelectShift(const Instruction *I) {
1702*9880d681SAndroid Build Coastguard Worker unsigned CReg = 0, OpReg = 0;
1703*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = nullptr;
1704*9880d681SAndroid Build Coastguard Worker if (I->getType()->isIntegerTy(8)) {
1705*9880d681SAndroid Build Coastguard Worker CReg = X86::CL;
1706*9880d681SAndroid Build Coastguard Worker RC = &X86::GR8RegClass;
1707*9880d681SAndroid Build Coastguard Worker switch (I->getOpcode()) {
1708*9880d681SAndroid Build Coastguard Worker case Instruction::LShr: OpReg = X86::SHR8rCL; break;
1709*9880d681SAndroid Build Coastguard Worker case Instruction::AShr: OpReg = X86::SAR8rCL; break;
1710*9880d681SAndroid Build Coastguard Worker case Instruction::Shl: OpReg = X86::SHL8rCL; break;
1711*9880d681SAndroid Build Coastguard Worker default: return false;
1712*9880d681SAndroid Build Coastguard Worker }
1713*9880d681SAndroid Build Coastguard Worker } else if (I->getType()->isIntegerTy(16)) {
1714*9880d681SAndroid Build Coastguard Worker CReg = X86::CX;
1715*9880d681SAndroid Build Coastguard Worker RC = &X86::GR16RegClass;
1716*9880d681SAndroid Build Coastguard Worker switch (I->getOpcode()) {
1717*9880d681SAndroid Build Coastguard Worker case Instruction::LShr: OpReg = X86::SHR16rCL; break;
1718*9880d681SAndroid Build Coastguard Worker case Instruction::AShr: OpReg = X86::SAR16rCL; break;
1719*9880d681SAndroid Build Coastguard Worker case Instruction::Shl: OpReg = X86::SHL16rCL; break;
1720*9880d681SAndroid Build Coastguard Worker default: return false;
1721*9880d681SAndroid Build Coastguard Worker }
1722*9880d681SAndroid Build Coastguard Worker } else if (I->getType()->isIntegerTy(32)) {
1723*9880d681SAndroid Build Coastguard Worker CReg = X86::ECX;
1724*9880d681SAndroid Build Coastguard Worker RC = &X86::GR32RegClass;
1725*9880d681SAndroid Build Coastguard Worker switch (I->getOpcode()) {
1726*9880d681SAndroid Build Coastguard Worker case Instruction::LShr: OpReg = X86::SHR32rCL; break;
1727*9880d681SAndroid Build Coastguard Worker case Instruction::AShr: OpReg = X86::SAR32rCL; break;
1728*9880d681SAndroid Build Coastguard Worker case Instruction::Shl: OpReg = X86::SHL32rCL; break;
1729*9880d681SAndroid Build Coastguard Worker default: return false;
1730*9880d681SAndroid Build Coastguard Worker }
1731*9880d681SAndroid Build Coastguard Worker } else if (I->getType()->isIntegerTy(64)) {
1732*9880d681SAndroid Build Coastguard Worker CReg = X86::RCX;
1733*9880d681SAndroid Build Coastguard Worker RC = &X86::GR64RegClass;
1734*9880d681SAndroid Build Coastguard Worker switch (I->getOpcode()) {
1735*9880d681SAndroid Build Coastguard Worker case Instruction::LShr: OpReg = X86::SHR64rCL; break;
1736*9880d681SAndroid Build Coastguard Worker case Instruction::AShr: OpReg = X86::SAR64rCL; break;
1737*9880d681SAndroid Build Coastguard Worker case Instruction::Shl: OpReg = X86::SHL64rCL; break;
1738*9880d681SAndroid Build Coastguard Worker default: return false;
1739*9880d681SAndroid Build Coastguard Worker }
1740*9880d681SAndroid Build Coastguard Worker } else {
1741*9880d681SAndroid Build Coastguard Worker return false;
1742*9880d681SAndroid Build Coastguard Worker }
1743*9880d681SAndroid Build Coastguard Worker
1744*9880d681SAndroid Build Coastguard Worker MVT VT;
1745*9880d681SAndroid Build Coastguard Worker if (!isTypeLegal(I->getType(), VT))
1746*9880d681SAndroid Build Coastguard Worker return false;
1747*9880d681SAndroid Build Coastguard Worker
1748*9880d681SAndroid Build Coastguard Worker unsigned Op0Reg = getRegForValue(I->getOperand(0));
1749*9880d681SAndroid Build Coastguard Worker if (Op0Reg == 0) return false;
1750*9880d681SAndroid Build Coastguard Worker
1751*9880d681SAndroid Build Coastguard Worker unsigned Op1Reg = getRegForValue(I->getOperand(1));
1752*9880d681SAndroid Build Coastguard Worker if (Op1Reg == 0) return false;
1753*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(TargetOpcode::COPY),
1754*9880d681SAndroid Build Coastguard Worker CReg).addReg(Op1Reg);
1755*9880d681SAndroid Build Coastguard Worker
1756*9880d681SAndroid Build Coastguard Worker // The shift instruction uses X86::CL. If we defined a super-register
1757*9880d681SAndroid Build Coastguard Worker // of X86::CL, emit a subreg KILL to precisely describe what we're doing here.
1758*9880d681SAndroid Build Coastguard Worker if (CReg != X86::CL)
1759*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1760*9880d681SAndroid Build Coastguard Worker TII.get(TargetOpcode::KILL), X86::CL)
1761*9880d681SAndroid Build Coastguard Worker .addReg(CReg, RegState::Kill);
1762*9880d681SAndroid Build Coastguard Worker
1763*9880d681SAndroid Build Coastguard Worker unsigned ResultReg = createResultReg(RC);
1764*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(OpReg), ResultReg)
1765*9880d681SAndroid Build Coastguard Worker .addReg(Op0Reg);
1766*9880d681SAndroid Build Coastguard Worker updateValueMap(I, ResultReg);
1767*9880d681SAndroid Build Coastguard Worker return true;
1768*9880d681SAndroid Build Coastguard Worker }
1769*9880d681SAndroid Build Coastguard Worker
X86SelectDivRem(const Instruction * I)1770*9880d681SAndroid Build Coastguard Worker bool X86FastISel::X86SelectDivRem(const Instruction *I) {
1771*9880d681SAndroid Build Coastguard Worker const static unsigned NumTypes = 4; // i8, i16, i32, i64
1772*9880d681SAndroid Build Coastguard Worker const static unsigned NumOps = 4; // SDiv, SRem, UDiv, URem
1773*9880d681SAndroid Build Coastguard Worker const static bool S = true; // IsSigned
1774*9880d681SAndroid Build Coastguard Worker const static bool U = false; // !IsSigned
1775*9880d681SAndroid Build Coastguard Worker const static unsigned Copy = TargetOpcode::COPY;
1776*9880d681SAndroid Build Coastguard Worker // For the X86 DIV/IDIV instruction, in most cases the dividend
1777*9880d681SAndroid Build Coastguard Worker // (numerator) must be in a specific register pair highreg:lowreg,
1778*9880d681SAndroid Build Coastguard Worker // producing the quotient in lowreg and the remainder in highreg.
1779*9880d681SAndroid Build Coastguard Worker // For most data types, to set up the instruction, the dividend is
1780*9880d681SAndroid Build Coastguard Worker // copied into lowreg, and lowreg is sign-extended or zero-extended
1781*9880d681SAndroid Build Coastguard Worker // into highreg. The exception is i8, where the dividend is defined
1782*9880d681SAndroid Build Coastguard Worker // as a single register rather than a register pair, and we
1783*9880d681SAndroid Build Coastguard Worker // therefore directly sign-extend or zero-extend the dividend into
1784*9880d681SAndroid Build Coastguard Worker // lowreg, instead of copying, and ignore the highreg.
1785*9880d681SAndroid Build Coastguard Worker const static struct DivRemEntry {
1786*9880d681SAndroid Build Coastguard Worker // The following portion depends only on the data type.
1787*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC;
1788*9880d681SAndroid Build Coastguard Worker unsigned LowInReg; // low part of the register pair
1789*9880d681SAndroid Build Coastguard Worker unsigned HighInReg; // high part of the register pair
1790*9880d681SAndroid Build Coastguard Worker // The following portion depends on both the data type and the operation.
1791*9880d681SAndroid Build Coastguard Worker struct DivRemResult {
1792*9880d681SAndroid Build Coastguard Worker unsigned OpDivRem; // The specific DIV/IDIV opcode to use.
1793*9880d681SAndroid Build Coastguard Worker unsigned OpSignExtend; // Opcode for sign-extending lowreg into
1794*9880d681SAndroid Build Coastguard Worker // highreg, or copying a zero into highreg.
1795*9880d681SAndroid Build Coastguard Worker unsigned OpCopy; // Opcode for copying dividend into lowreg, or
1796*9880d681SAndroid Build Coastguard Worker // zero/sign-extending into lowreg for i8.
1797*9880d681SAndroid Build Coastguard Worker unsigned DivRemResultReg; // Register containing the desired result.
1798*9880d681SAndroid Build Coastguard Worker bool IsOpSigned; // Whether to use signed or unsigned form.
1799*9880d681SAndroid Build Coastguard Worker } ResultTable[NumOps];
1800*9880d681SAndroid Build Coastguard Worker } OpTable[NumTypes] = {
1801*9880d681SAndroid Build Coastguard Worker { &X86::GR8RegClass, X86::AX, 0, {
1802*9880d681SAndroid Build Coastguard Worker { X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AL, S }, // SDiv
1803*9880d681SAndroid Build Coastguard Worker { X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AH, S }, // SRem
1804*9880d681SAndroid Build Coastguard Worker { X86::DIV8r, 0, X86::MOVZX16rr8, X86::AL, U }, // UDiv
1805*9880d681SAndroid Build Coastguard Worker { X86::DIV8r, 0, X86::MOVZX16rr8, X86::AH, U }, // URem
1806*9880d681SAndroid Build Coastguard Worker }
1807*9880d681SAndroid Build Coastguard Worker }, // i8
1808*9880d681SAndroid Build Coastguard Worker { &X86::GR16RegClass, X86::AX, X86::DX, {
1809*9880d681SAndroid Build Coastguard Worker { X86::IDIV16r, X86::CWD, Copy, X86::AX, S }, // SDiv
1810*9880d681SAndroid Build Coastguard Worker { X86::IDIV16r, X86::CWD, Copy, X86::DX, S }, // SRem
1811*9880d681SAndroid Build Coastguard Worker { X86::DIV16r, X86::MOV32r0, Copy, X86::AX, U }, // UDiv
1812*9880d681SAndroid Build Coastguard Worker { X86::DIV16r, X86::MOV32r0, Copy, X86::DX, U }, // URem
1813*9880d681SAndroid Build Coastguard Worker }
1814*9880d681SAndroid Build Coastguard Worker }, // i16
1815*9880d681SAndroid Build Coastguard Worker { &X86::GR32RegClass, X86::EAX, X86::EDX, {
1816*9880d681SAndroid Build Coastguard Worker { X86::IDIV32r, X86::CDQ, Copy, X86::EAX, S }, // SDiv
1817*9880d681SAndroid Build Coastguard Worker { X86::IDIV32r, X86::CDQ, Copy, X86::EDX, S }, // SRem
1818*9880d681SAndroid Build Coastguard Worker { X86::DIV32r, X86::MOV32r0, Copy, X86::EAX, U }, // UDiv
1819*9880d681SAndroid Build Coastguard Worker { X86::DIV32r, X86::MOV32r0, Copy, X86::EDX, U }, // URem
1820*9880d681SAndroid Build Coastguard Worker }
1821*9880d681SAndroid Build Coastguard Worker }, // i32
1822*9880d681SAndroid Build Coastguard Worker { &X86::GR64RegClass, X86::RAX, X86::RDX, {
1823*9880d681SAndroid Build Coastguard Worker { X86::IDIV64r, X86::CQO, Copy, X86::RAX, S }, // SDiv
1824*9880d681SAndroid Build Coastguard Worker { X86::IDIV64r, X86::CQO, Copy, X86::RDX, S }, // SRem
1825*9880d681SAndroid Build Coastguard Worker { X86::DIV64r, X86::MOV32r0, Copy, X86::RAX, U }, // UDiv
1826*9880d681SAndroid Build Coastguard Worker { X86::DIV64r, X86::MOV32r0, Copy, X86::RDX, U }, // URem
1827*9880d681SAndroid Build Coastguard Worker }
1828*9880d681SAndroid Build Coastguard Worker }, // i64
1829*9880d681SAndroid Build Coastguard Worker };
1830*9880d681SAndroid Build Coastguard Worker
1831*9880d681SAndroid Build Coastguard Worker MVT VT;
1832*9880d681SAndroid Build Coastguard Worker if (!isTypeLegal(I->getType(), VT))
1833*9880d681SAndroid Build Coastguard Worker return false;
1834*9880d681SAndroid Build Coastguard Worker
1835*9880d681SAndroid Build Coastguard Worker unsigned TypeIndex, OpIndex;
1836*9880d681SAndroid Build Coastguard Worker switch (VT.SimpleTy) {
1837*9880d681SAndroid Build Coastguard Worker default: return false;
1838*9880d681SAndroid Build Coastguard Worker case MVT::i8: TypeIndex = 0; break;
1839*9880d681SAndroid Build Coastguard Worker case MVT::i16: TypeIndex = 1; break;
1840*9880d681SAndroid Build Coastguard Worker case MVT::i32: TypeIndex = 2; break;
1841*9880d681SAndroid Build Coastguard Worker case MVT::i64: TypeIndex = 3;
1842*9880d681SAndroid Build Coastguard Worker if (!Subtarget->is64Bit())
1843*9880d681SAndroid Build Coastguard Worker return false;
1844*9880d681SAndroid Build Coastguard Worker break;
1845*9880d681SAndroid Build Coastguard Worker }
1846*9880d681SAndroid Build Coastguard Worker
1847*9880d681SAndroid Build Coastguard Worker switch (I->getOpcode()) {
1848*9880d681SAndroid Build Coastguard Worker default: llvm_unreachable("Unexpected div/rem opcode");
1849*9880d681SAndroid Build Coastguard Worker case Instruction::SDiv: OpIndex = 0; break;
1850*9880d681SAndroid Build Coastguard Worker case Instruction::SRem: OpIndex = 1; break;
1851*9880d681SAndroid Build Coastguard Worker case Instruction::UDiv: OpIndex = 2; break;
1852*9880d681SAndroid Build Coastguard Worker case Instruction::URem: OpIndex = 3; break;
1853*9880d681SAndroid Build Coastguard Worker }
1854*9880d681SAndroid Build Coastguard Worker
1855*9880d681SAndroid Build Coastguard Worker const DivRemEntry &TypeEntry = OpTable[TypeIndex];
1856*9880d681SAndroid Build Coastguard Worker const DivRemEntry::DivRemResult &OpEntry = TypeEntry.ResultTable[OpIndex];
1857*9880d681SAndroid Build Coastguard Worker unsigned Op0Reg = getRegForValue(I->getOperand(0));
1858*9880d681SAndroid Build Coastguard Worker if (Op0Reg == 0)
1859*9880d681SAndroid Build Coastguard Worker return false;
1860*9880d681SAndroid Build Coastguard Worker unsigned Op1Reg = getRegForValue(I->getOperand(1));
1861*9880d681SAndroid Build Coastguard Worker if (Op1Reg == 0)
1862*9880d681SAndroid Build Coastguard Worker return false;
1863*9880d681SAndroid Build Coastguard Worker
1864*9880d681SAndroid Build Coastguard Worker // Move op0 into low-order input register.
1865*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1866*9880d681SAndroid Build Coastguard Worker TII.get(OpEntry.OpCopy), TypeEntry.LowInReg).addReg(Op0Reg);
1867*9880d681SAndroid Build Coastguard Worker // Zero-extend or sign-extend into high-order input register.
1868*9880d681SAndroid Build Coastguard Worker if (OpEntry.OpSignExtend) {
1869*9880d681SAndroid Build Coastguard Worker if (OpEntry.IsOpSigned)
1870*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1871*9880d681SAndroid Build Coastguard Worker TII.get(OpEntry.OpSignExtend));
1872*9880d681SAndroid Build Coastguard Worker else {
1873*9880d681SAndroid Build Coastguard Worker unsigned Zero32 = createResultReg(&X86::GR32RegClass);
1874*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1875*9880d681SAndroid Build Coastguard Worker TII.get(X86::MOV32r0), Zero32);
1876*9880d681SAndroid Build Coastguard Worker
1877*9880d681SAndroid Build Coastguard Worker // Copy the zero into the appropriate sub/super/identical physical
1878*9880d681SAndroid Build Coastguard Worker // register. Unfortunately the operations needed are not uniform enough
1879*9880d681SAndroid Build Coastguard Worker // to fit neatly into the table above.
1880*9880d681SAndroid Build Coastguard Worker if (VT.SimpleTy == MVT::i16) {
1881*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1882*9880d681SAndroid Build Coastguard Worker TII.get(Copy), TypeEntry.HighInReg)
1883*9880d681SAndroid Build Coastguard Worker .addReg(Zero32, 0, X86::sub_16bit);
1884*9880d681SAndroid Build Coastguard Worker } else if (VT.SimpleTy == MVT::i32) {
1885*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1886*9880d681SAndroid Build Coastguard Worker TII.get(Copy), TypeEntry.HighInReg)
1887*9880d681SAndroid Build Coastguard Worker .addReg(Zero32);
1888*9880d681SAndroid Build Coastguard Worker } else if (VT.SimpleTy == MVT::i64) {
1889*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1890*9880d681SAndroid Build Coastguard Worker TII.get(TargetOpcode::SUBREG_TO_REG), TypeEntry.HighInReg)
1891*9880d681SAndroid Build Coastguard Worker .addImm(0).addReg(Zero32).addImm(X86::sub_32bit);
1892*9880d681SAndroid Build Coastguard Worker }
1893*9880d681SAndroid Build Coastguard Worker }
1894*9880d681SAndroid Build Coastguard Worker }
1895*9880d681SAndroid Build Coastguard Worker // Generate the DIV/IDIV instruction.
1896*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1897*9880d681SAndroid Build Coastguard Worker TII.get(OpEntry.OpDivRem)).addReg(Op1Reg);
1898*9880d681SAndroid Build Coastguard Worker // For i8 remainder, we can't reference AH directly, as we'll end
1899*9880d681SAndroid Build Coastguard Worker // up with bogus copies like %R9B = COPY %AH. Reference AX
1900*9880d681SAndroid Build Coastguard Worker // instead to prevent AH references in a REX instruction.
1901*9880d681SAndroid Build Coastguard Worker //
1902*9880d681SAndroid Build Coastguard Worker // The current assumption of the fast register allocator is that isel
1903*9880d681SAndroid Build Coastguard Worker // won't generate explicit references to the GPR8_NOREX registers. If
1904*9880d681SAndroid Build Coastguard Worker // the allocator and/or the backend get enhanced to be more robust in
1905*9880d681SAndroid Build Coastguard Worker // that regard, this can be, and should be, removed.
1906*9880d681SAndroid Build Coastguard Worker unsigned ResultReg = 0;
1907*9880d681SAndroid Build Coastguard Worker if ((I->getOpcode() == Instruction::SRem ||
1908*9880d681SAndroid Build Coastguard Worker I->getOpcode() == Instruction::URem) &&
1909*9880d681SAndroid Build Coastguard Worker OpEntry.DivRemResultReg == X86::AH && Subtarget->is64Bit()) {
1910*9880d681SAndroid Build Coastguard Worker unsigned SourceSuperReg = createResultReg(&X86::GR16RegClass);
1911*9880d681SAndroid Build Coastguard Worker unsigned ResultSuperReg = createResultReg(&X86::GR16RegClass);
1912*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1913*9880d681SAndroid Build Coastguard Worker TII.get(Copy), SourceSuperReg).addReg(X86::AX);
1914*9880d681SAndroid Build Coastguard Worker
1915*9880d681SAndroid Build Coastguard Worker // Shift AX right by 8 bits instead of using AH.
1916*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::SHR16ri),
1917*9880d681SAndroid Build Coastguard Worker ResultSuperReg).addReg(SourceSuperReg).addImm(8);
1918*9880d681SAndroid Build Coastguard Worker
1919*9880d681SAndroid Build Coastguard Worker // Now reference the 8-bit subreg of the result.
1920*9880d681SAndroid Build Coastguard Worker ResultReg = fastEmitInst_extractsubreg(MVT::i8, ResultSuperReg,
1921*9880d681SAndroid Build Coastguard Worker /*Kill=*/true, X86::sub_8bit);
1922*9880d681SAndroid Build Coastguard Worker }
1923*9880d681SAndroid Build Coastguard Worker // Copy the result out of the physreg if we haven't already.
1924*9880d681SAndroid Build Coastguard Worker if (!ResultReg) {
1925*9880d681SAndroid Build Coastguard Worker ResultReg = createResultReg(TypeEntry.RC);
1926*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Copy), ResultReg)
1927*9880d681SAndroid Build Coastguard Worker .addReg(OpEntry.DivRemResultReg);
1928*9880d681SAndroid Build Coastguard Worker }
1929*9880d681SAndroid Build Coastguard Worker updateValueMap(I, ResultReg);
1930*9880d681SAndroid Build Coastguard Worker
1931*9880d681SAndroid Build Coastguard Worker return true;
1932*9880d681SAndroid Build Coastguard Worker }
1933*9880d681SAndroid Build Coastguard Worker
1934*9880d681SAndroid Build Coastguard Worker /// \brief Emit a conditional move instruction (if the are supported) to lower
1935*9880d681SAndroid Build Coastguard Worker /// the select.
X86FastEmitCMoveSelect(MVT RetVT,const Instruction * I)1936*9880d681SAndroid Build Coastguard Worker bool X86FastISel::X86FastEmitCMoveSelect(MVT RetVT, const Instruction *I) {
1937*9880d681SAndroid Build Coastguard Worker // Check if the subtarget supports these instructions.
1938*9880d681SAndroid Build Coastguard Worker if (!Subtarget->hasCMov())
1939*9880d681SAndroid Build Coastguard Worker return false;
1940*9880d681SAndroid Build Coastguard Worker
1941*9880d681SAndroid Build Coastguard Worker // FIXME: Add support for i8.
1942*9880d681SAndroid Build Coastguard Worker if (RetVT < MVT::i16 || RetVT > MVT::i64)
1943*9880d681SAndroid Build Coastguard Worker return false;
1944*9880d681SAndroid Build Coastguard Worker
1945*9880d681SAndroid Build Coastguard Worker const Value *Cond = I->getOperand(0);
1946*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = TLI.getRegClassFor(RetVT);
1947*9880d681SAndroid Build Coastguard Worker bool NeedTest = true;
1948*9880d681SAndroid Build Coastguard Worker X86::CondCode CC = X86::COND_NE;
1949*9880d681SAndroid Build Coastguard Worker
1950*9880d681SAndroid Build Coastguard Worker // Optimize conditions coming from a compare if both instructions are in the
1951*9880d681SAndroid Build Coastguard Worker // same basic block (values defined in other basic blocks may not have
1952*9880d681SAndroid Build Coastguard Worker // initialized registers).
1953*9880d681SAndroid Build Coastguard Worker const auto *CI = dyn_cast<CmpInst>(Cond);
1954*9880d681SAndroid Build Coastguard Worker if (CI && (CI->getParent() == I->getParent())) {
1955*9880d681SAndroid Build Coastguard Worker CmpInst::Predicate Predicate = optimizeCmpPredicate(CI);
1956*9880d681SAndroid Build Coastguard Worker
1957*9880d681SAndroid Build Coastguard Worker // FCMP_OEQ and FCMP_UNE cannot be checked with a single instruction.
1958*9880d681SAndroid Build Coastguard Worker static unsigned SETFOpcTable[2][3] = {
1959*9880d681SAndroid Build Coastguard Worker { X86::SETNPr, X86::SETEr , X86::TEST8rr },
1960*9880d681SAndroid Build Coastguard Worker { X86::SETPr, X86::SETNEr, X86::OR8rr }
1961*9880d681SAndroid Build Coastguard Worker };
1962*9880d681SAndroid Build Coastguard Worker unsigned *SETFOpc = nullptr;
1963*9880d681SAndroid Build Coastguard Worker switch (Predicate) {
1964*9880d681SAndroid Build Coastguard Worker default: break;
1965*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_OEQ:
1966*9880d681SAndroid Build Coastguard Worker SETFOpc = &SETFOpcTable[0][0];
1967*9880d681SAndroid Build Coastguard Worker Predicate = CmpInst::ICMP_NE;
1968*9880d681SAndroid Build Coastguard Worker break;
1969*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_UNE:
1970*9880d681SAndroid Build Coastguard Worker SETFOpc = &SETFOpcTable[1][0];
1971*9880d681SAndroid Build Coastguard Worker Predicate = CmpInst::ICMP_NE;
1972*9880d681SAndroid Build Coastguard Worker break;
1973*9880d681SAndroid Build Coastguard Worker }
1974*9880d681SAndroid Build Coastguard Worker
1975*9880d681SAndroid Build Coastguard Worker bool NeedSwap;
1976*9880d681SAndroid Build Coastguard Worker std::tie(CC, NeedSwap) = getX86ConditionCode(Predicate);
1977*9880d681SAndroid Build Coastguard Worker assert(CC <= X86::LAST_VALID_COND && "Unexpected condition code.");
1978*9880d681SAndroid Build Coastguard Worker
1979*9880d681SAndroid Build Coastguard Worker const Value *CmpLHS = CI->getOperand(0);
1980*9880d681SAndroid Build Coastguard Worker const Value *CmpRHS = CI->getOperand(1);
1981*9880d681SAndroid Build Coastguard Worker if (NeedSwap)
1982*9880d681SAndroid Build Coastguard Worker std::swap(CmpLHS, CmpRHS);
1983*9880d681SAndroid Build Coastguard Worker
1984*9880d681SAndroid Build Coastguard Worker EVT CmpVT = TLI.getValueType(DL, CmpLHS->getType());
1985*9880d681SAndroid Build Coastguard Worker // Emit a compare of the LHS and RHS, setting the flags.
1986*9880d681SAndroid Build Coastguard Worker if (!X86FastEmitCompare(CmpLHS, CmpRHS, CmpVT, CI->getDebugLoc()))
1987*9880d681SAndroid Build Coastguard Worker return false;
1988*9880d681SAndroid Build Coastguard Worker
1989*9880d681SAndroid Build Coastguard Worker if (SETFOpc) {
1990*9880d681SAndroid Build Coastguard Worker unsigned FlagReg1 = createResultReg(&X86::GR8RegClass);
1991*9880d681SAndroid Build Coastguard Worker unsigned FlagReg2 = createResultReg(&X86::GR8RegClass);
1992*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(SETFOpc[0]),
1993*9880d681SAndroid Build Coastguard Worker FlagReg1);
1994*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(SETFOpc[1]),
1995*9880d681SAndroid Build Coastguard Worker FlagReg2);
1996*9880d681SAndroid Build Coastguard Worker auto const &II = TII.get(SETFOpc[2]);
1997*9880d681SAndroid Build Coastguard Worker if (II.getNumDefs()) {
1998*9880d681SAndroid Build Coastguard Worker unsigned TmpReg = createResultReg(&X86::GR8RegClass);
1999*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II, TmpReg)
2000*9880d681SAndroid Build Coastguard Worker .addReg(FlagReg2).addReg(FlagReg1);
2001*9880d681SAndroid Build Coastguard Worker } else {
2002*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II)
2003*9880d681SAndroid Build Coastguard Worker .addReg(FlagReg2).addReg(FlagReg1);
2004*9880d681SAndroid Build Coastguard Worker }
2005*9880d681SAndroid Build Coastguard Worker }
2006*9880d681SAndroid Build Coastguard Worker NeedTest = false;
2007*9880d681SAndroid Build Coastguard Worker } else if (foldX86XALUIntrinsic(CC, I, Cond)) {
2008*9880d681SAndroid Build Coastguard Worker // Fake request the condition, otherwise the intrinsic might be completely
2009*9880d681SAndroid Build Coastguard Worker // optimized away.
2010*9880d681SAndroid Build Coastguard Worker unsigned TmpReg = getRegForValue(Cond);
2011*9880d681SAndroid Build Coastguard Worker if (TmpReg == 0)
2012*9880d681SAndroid Build Coastguard Worker return false;
2013*9880d681SAndroid Build Coastguard Worker
2014*9880d681SAndroid Build Coastguard Worker NeedTest = false;
2015*9880d681SAndroid Build Coastguard Worker }
2016*9880d681SAndroid Build Coastguard Worker
2017*9880d681SAndroid Build Coastguard Worker if (NeedTest) {
2018*9880d681SAndroid Build Coastguard Worker // Selects operate on i1, however, CondReg is 8 bits width and may contain
2019*9880d681SAndroid Build Coastguard Worker // garbage. Indeed, only the less significant bit is supposed to be
2020*9880d681SAndroid Build Coastguard Worker // accurate. If we read more than the lsb, we may see non-zero values
2021*9880d681SAndroid Build Coastguard Worker // whereas lsb is zero. Therefore, we have to truncate Op0Reg to i1 for
2022*9880d681SAndroid Build Coastguard Worker // the select. This is achieved by performing TEST against 1.
2023*9880d681SAndroid Build Coastguard Worker unsigned CondReg = getRegForValue(Cond);
2024*9880d681SAndroid Build Coastguard Worker if (CondReg == 0)
2025*9880d681SAndroid Build Coastguard Worker return false;
2026*9880d681SAndroid Build Coastguard Worker bool CondIsKill = hasTrivialKill(Cond);
2027*9880d681SAndroid Build Coastguard Worker
2028*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::TEST8ri))
2029*9880d681SAndroid Build Coastguard Worker .addReg(CondReg, getKillRegState(CondIsKill)).addImm(1);
2030*9880d681SAndroid Build Coastguard Worker }
2031*9880d681SAndroid Build Coastguard Worker
2032*9880d681SAndroid Build Coastguard Worker const Value *LHS = I->getOperand(1);
2033*9880d681SAndroid Build Coastguard Worker const Value *RHS = I->getOperand(2);
2034*9880d681SAndroid Build Coastguard Worker
2035*9880d681SAndroid Build Coastguard Worker unsigned RHSReg = getRegForValue(RHS);
2036*9880d681SAndroid Build Coastguard Worker bool RHSIsKill = hasTrivialKill(RHS);
2037*9880d681SAndroid Build Coastguard Worker
2038*9880d681SAndroid Build Coastguard Worker unsigned LHSReg = getRegForValue(LHS);
2039*9880d681SAndroid Build Coastguard Worker bool LHSIsKill = hasTrivialKill(LHS);
2040*9880d681SAndroid Build Coastguard Worker
2041*9880d681SAndroid Build Coastguard Worker if (!LHSReg || !RHSReg)
2042*9880d681SAndroid Build Coastguard Worker return false;
2043*9880d681SAndroid Build Coastguard Worker
2044*9880d681SAndroid Build Coastguard Worker unsigned Opc = X86::getCMovFromCond(CC, RC->getSize());
2045*9880d681SAndroid Build Coastguard Worker unsigned ResultReg = fastEmitInst_rr(Opc, RC, RHSReg, RHSIsKill,
2046*9880d681SAndroid Build Coastguard Worker LHSReg, LHSIsKill);
2047*9880d681SAndroid Build Coastguard Worker updateValueMap(I, ResultReg);
2048*9880d681SAndroid Build Coastguard Worker return true;
2049*9880d681SAndroid Build Coastguard Worker }
2050*9880d681SAndroid Build Coastguard Worker
2051*9880d681SAndroid Build Coastguard Worker /// \brief Emit SSE or AVX instructions to lower the select.
2052*9880d681SAndroid Build Coastguard Worker ///
2053*9880d681SAndroid Build Coastguard Worker /// Try to use SSE1/SSE2 instructions to simulate a select without branches.
2054*9880d681SAndroid Build Coastguard Worker /// This lowers fp selects into a CMP/AND/ANDN/OR sequence when the necessary
2055*9880d681SAndroid Build Coastguard Worker /// SSE instructions are available. If AVX is available, try to use a VBLENDV.
X86FastEmitSSESelect(MVT RetVT,const Instruction * I)2056*9880d681SAndroid Build Coastguard Worker bool X86FastISel::X86FastEmitSSESelect(MVT RetVT, const Instruction *I) {
2057*9880d681SAndroid Build Coastguard Worker // Optimize conditions coming from a compare if both instructions are in the
2058*9880d681SAndroid Build Coastguard Worker // same basic block (values defined in other basic blocks may not have
2059*9880d681SAndroid Build Coastguard Worker // initialized registers).
2060*9880d681SAndroid Build Coastguard Worker const auto *CI = dyn_cast<FCmpInst>(I->getOperand(0));
2061*9880d681SAndroid Build Coastguard Worker if (!CI || (CI->getParent() != I->getParent()))
2062*9880d681SAndroid Build Coastguard Worker return false;
2063*9880d681SAndroid Build Coastguard Worker
2064*9880d681SAndroid Build Coastguard Worker if (I->getType() != CI->getOperand(0)->getType() ||
2065*9880d681SAndroid Build Coastguard Worker !((Subtarget->hasSSE1() && RetVT == MVT::f32) ||
2066*9880d681SAndroid Build Coastguard Worker (Subtarget->hasSSE2() && RetVT == MVT::f64)))
2067*9880d681SAndroid Build Coastguard Worker return false;
2068*9880d681SAndroid Build Coastguard Worker
2069*9880d681SAndroid Build Coastguard Worker const Value *CmpLHS = CI->getOperand(0);
2070*9880d681SAndroid Build Coastguard Worker const Value *CmpRHS = CI->getOperand(1);
2071*9880d681SAndroid Build Coastguard Worker CmpInst::Predicate Predicate = optimizeCmpPredicate(CI);
2072*9880d681SAndroid Build Coastguard Worker
2073*9880d681SAndroid Build Coastguard Worker // The optimizer might have replaced fcmp oeq %x, %x with fcmp ord %x, 0.0.
2074*9880d681SAndroid Build Coastguard Worker // We don't have to materialize a zero constant for this case and can just use
2075*9880d681SAndroid Build Coastguard Worker // %x again on the RHS.
2076*9880d681SAndroid Build Coastguard Worker if (Predicate == CmpInst::FCMP_ORD || Predicate == CmpInst::FCMP_UNO) {
2077*9880d681SAndroid Build Coastguard Worker const auto *CmpRHSC = dyn_cast<ConstantFP>(CmpRHS);
2078*9880d681SAndroid Build Coastguard Worker if (CmpRHSC && CmpRHSC->isNullValue())
2079*9880d681SAndroid Build Coastguard Worker CmpRHS = CmpLHS;
2080*9880d681SAndroid Build Coastguard Worker }
2081*9880d681SAndroid Build Coastguard Worker
2082*9880d681SAndroid Build Coastguard Worker unsigned CC;
2083*9880d681SAndroid Build Coastguard Worker bool NeedSwap;
2084*9880d681SAndroid Build Coastguard Worker std::tie(CC, NeedSwap) = getX86SSEConditionCode(Predicate);
2085*9880d681SAndroid Build Coastguard Worker if (CC > 7)
2086*9880d681SAndroid Build Coastguard Worker return false;
2087*9880d681SAndroid Build Coastguard Worker
2088*9880d681SAndroid Build Coastguard Worker if (NeedSwap)
2089*9880d681SAndroid Build Coastguard Worker std::swap(CmpLHS, CmpRHS);
2090*9880d681SAndroid Build Coastguard Worker
2091*9880d681SAndroid Build Coastguard Worker // Choose the SSE instruction sequence based on data type (float or double).
2092*9880d681SAndroid Build Coastguard Worker static unsigned OpcTable[2][4] = {
2093*9880d681SAndroid Build Coastguard Worker { X86::CMPSSrr, X86::FsANDPSrr, X86::FsANDNPSrr, X86::FsORPSrr },
2094*9880d681SAndroid Build Coastguard Worker { X86::CMPSDrr, X86::FsANDPDrr, X86::FsANDNPDrr, X86::FsORPDrr }
2095*9880d681SAndroid Build Coastguard Worker };
2096*9880d681SAndroid Build Coastguard Worker
2097*9880d681SAndroid Build Coastguard Worker unsigned *Opc = nullptr;
2098*9880d681SAndroid Build Coastguard Worker switch (RetVT.SimpleTy) {
2099*9880d681SAndroid Build Coastguard Worker default: return false;
2100*9880d681SAndroid Build Coastguard Worker case MVT::f32: Opc = &OpcTable[0][0]; break;
2101*9880d681SAndroid Build Coastguard Worker case MVT::f64: Opc = &OpcTable[1][0]; break;
2102*9880d681SAndroid Build Coastguard Worker }
2103*9880d681SAndroid Build Coastguard Worker
2104*9880d681SAndroid Build Coastguard Worker const Value *LHS = I->getOperand(1);
2105*9880d681SAndroid Build Coastguard Worker const Value *RHS = I->getOperand(2);
2106*9880d681SAndroid Build Coastguard Worker
2107*9880d681SAndroid Build Coastguard Worker unsigned LHSReg = getRegForValue(LHS);
2108*9880d681SAndroid Build Coastguard Worker bool LHSIsKill = hasTrivialKill(LHS);
2109*9880d681SAndroid Build Coastguard Worker
2110*9880d681SAndroid Build Coastguard Worker unsigned RHSReg = getRegForValue(RHS);
2111*9880d681SAndroid Build Coastguard Worker bool RHSIsKill = hasTrivialKill(RHS);
2112*9880d681SAndroid Build Coastguard Worker
2113*9880d681SAndroid Build Coastguard Worker unsigned CmpLHSReg = getRegForValue(CmpLHS);
2114*9880d681SAndroid Build Coastguard Worker bool CmpLHSIsKill = hasTrivialKill(CmpLHS);
2115*9880d681SAndroid Build Coastguard Worker
2116*9880d681SAndroid Build Coastguard Worker unsigned CmpRHSReg = getRegForValue(CmpRHS);
2117*9880d681SAndroid Build Coastguard Worker bool CmpRHSIsKill = hasTrivialKill(CmpRHS);
2118*9880d681SAndroid Build Coastguard Worker
2119*9880d681SAndroid Build Coastguard Worker if (!LHSReg || !RHSReg || !CmpLHS || !CmpRHS)
2120*9880d681SAndroid Build Coastguard Worker return false;
2121*9880d681SAndroid Build Coastguard Worker
2122*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = TLI.getRegClassFor(RetVT);
2123*9880d681SAndroid Build Coastguard Worker unsigned ResultReg;
2124*9880d681SAndroid Build Coastguard Worker
2125*9880d681SAndroid Build Coastguard Worker if (Subtarget->hasAVX()) {
2126*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *FR32 = &X86::FR32RegClass;
2127*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *VR128 = &X86::VR128RegClass;
2128*9880d681SAndroid Build Coastguard Worker
2129*9880d681SAndroid Build Coastguard Worker // If we have AVX, create 1 blendv instead of 3 logic instructions.
2130*9880d681SAndroid Build Coastguard Worker // Blendv was introduced with SSE 4.1, but the 2 register form implicitly
2131*9880d681SAndroid Build Coastguard Worker // uses XMM0 as the selection register. That may need just as many
2132*9880d681SAndroid Build Coastguard Worker // instructions as the AND/ANDN/OR sequence due to register moves, so
2133*9880d681SAndroid Build Coastguard Worker // don't bother.
2134*9880d681SAndroid Build Coastguard Worker unsigned CmpOpcode =
2135*9880d681SAndroid Build Coastguard Worker (RetVT.SimpleTy == MVT::f32) ? X86::VCMPSSrr : X86::VCMPSDrr;
2136*9880d681SAndroid Build Coastguard Worker unsigned BlendOpcode =
2137*9880d681SAndroid Build Coastguard Worker (RetVT.SimpleTy == MVT::f32) ? X86::VBLENDVPSrr : X86::VBLENDVPDrr;
2138*9880d681SAndroid Build Coastguard Worker
2139*9880d681SAndroid Build Coastguard Worker unsigned CmpReg = fastEmitInst_rri(CmpOpcode, FR32, CmpLHSReg, CmpLHSIsKill,
2140*9880d681SAndroid Build Coastguard Worker CmpRHSReg, CmpRHSIsKill, CC);
2141*9880d681SAndroid Build Coastguard Worker unsigned VBlendReg = fastEmitInst_rrr(BlendOpcode, VR128, RHSReg, RHSIsKill,
2142*9880d681SAndroid Build Coastguard Worker LHSReg, LHSIsKill, CmpReg, true);
2143*9880d681SAndroid Build Coastguard Worker ResultReg = createResultReg(RC);
2144*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2145*9880d681SAndroid Build Coastguard Worker TII.get(TargetOpcode::COPY), ResultReg).addReg(VBlendReg);
2146*9880d681SAndroid Build Coastguard Worker } else {
2147*9880d681SAndroid Build Coastguard Worker unsigned CmpReg = fastEmitInst_rri(Opc[0], RC, CmpLHSReg, CmpLHSIsKill,
2148*9880d681SAndroid Build Coastguard Worker CmpRHSReg, CmpRHSIsKill, CC);
2149*9880d681SAndroid Build Coastguard Worker unsigned AndReg = fastEmitInst_rr(Opc[1], RC, CmpReg, /*IsKill=*/false,
2150*9880d681SAndroid Build Coastguard Worker LHSReg, LHSIsKill);
2151*9880d681SAndroid Build Coastguard Worker unsigned AndNReg = fastEmitInst_rr(Opc[2], RC, CmpReg, /*IsKill=*/true,
2152*9880d681SAndroid Build Coastguard Worker RHSReg, RHSIsKill);
2153*9880d681SAndroid Build Coastguard Worker ResultReg = fastEmitInst_rr(Opc[3], RC, AndNReg, /*IsKill=*/true,
2154*9880d681SAndroid Build Coastguard Worker AndReg, /*IsKill=*/true);
2155*9880d681SAndroid Build Coastguard Worker }
2156*9880d681SAndroid Build Coastguard Worker updateValueMap(I, ResultReg);
2157*9880d681SAndroid Build Coastguard Worker return true;
2158*9880d681SAndroid Build Coastguard Worker }
2159*9880d681SAndroid Build Coastguard Worker
X86FastEmitPseudoSelect(MVT RetVT,const Instruction * I)2160*9880d681SAndroid Build Coastguard Worker bool X86FastISel::X86FastEmitPseudoSelect(MVT RetVT, const Instruction *I) {
2161*9880d681SAndroid Build Coastguard Worker // These are pseudo CMOV instructions and will be later expanded into control-
2162*9880d681SAndroid Build Coastguard Worker // flow.
2163*9880d681SAndroid Build Coastguard Worker unsigned Opc;
2164*9880d681SAndroid Build Coastguard Worker switch (RetVT.SimpleTy) {
2165*9880d681SAndroid Build Coastguard Worker default: return false;
2166*9880d681SAndroid Build Coastguard Worker case MVT::i8: Opc = X86::CMOV_GR8; break;
2167*9880d681SAndroid Build Coastguard Worker case MVT::i16: Opc = X86::CMOV_GR16; break;
2168*9880d681SAndroid Build Coastguard Worker case MVT::i32: Opc = X86::CMOV_GR32; break;
2169*9880d681SAndroid Build Coastguard Worker case MVT::f32: Opc = X86::CMOV_FR32; break;
2170*9880d681SAndroid Build Coastguard Worker case MVT::f64: Opc = X86::CMOV_FR64; break;
2171*9880d681SAndroid Build Coastguard Worker }
2172*9880d681SAndroid Build Coastguard Worker
2173*9880d681SAndroid Build Coastguard Worker const Value *Cond = I->getOperand(0);
2174*9880d681SAndroid Build Coastguard Worker X86::CondCode CC = X86::COND_NE;
2175*9880d681SAndroid Build Coastguard Worker
2176*9880d681SAndroid Build Coastguard Worker // Optimize conditions coming from a compare if both instructions are in the
2177*9880d681SAndroid Build Coastguard Worker // same basic block (values defined in other basic blocks may not have
2178*9880d681SAndroid Build Coastguard Worker // initialized registers).
2179*9880d681SAndroid Build Coastguard Worker const auto *CI = dyn_cast<CmpInst>(Cond);
2180*9880d681SAndroid Build Coastguard Worker if (CI && (CI->getParent() == I->getParent())) {
2181*9880d681SAndroid Build Coastguard Worker bool NeedSwap;
2182*9880d681SAndroid Build Coastguard Worker std::tie(CC, NeedSwap) = getX86ConditionCode(CI->getPredicate());
2183*9880d681SAndroid Build Coastguard Worker if (CC > X86::LAST_VALID_COND)
2184*9880d681SAndroid Build Coastguard Worker return false;
2185*9880d681SAndroid Build Coastguard Worker
2186*9880d681SAndroid Build Coastguard Worker const Value *CmpLHS = CI->getOperand(0);
2187*9880d681SAndroid Build Coastguard Worker const Value *CmpRHS = CI->getOperand(1);
2188*9880d681SAndroid Build Coastguard Worker
2189*9880d681SAndroid Build Coastguard Worker if (NeedSwap)
2190*9880d681SAndroid Build Coastguard Worker std::swap(CmpLHS, CmpRHS);
2191*9880d681SAndroid Build Coastguard Worker
2192*9880d681SAndroid Build Coastguard Worker EVT CmpVT = TLI.getValueType(DL, CmpLHS->getType());
2193*9880d681SAndroid Build Coastguard Worker if (!X86FastEmitCompare(CmpLHS, CmpRHS, CmpVT, CI->getDebugLoc()))
2194*9880d681SAndroid Build Coastguard Worker return false;
2195*9880d681SAndroid Build Coastguard Worker } else {
2196*9880d681SAndroid Build Coastguard Worker unsigned CondReg = getRegForValue(Cond);
2197*9880d681SAndroid Build Coastguard Worker if (CondReg == 0)
2198*9880d681SAndroid Build Coastguard Worker return false;
2199*9880d681SAndroid Build Coastguard Worker bool CondIsKill = hasTrivialKill(Cond);
2200*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::TEST8ri))
2201*9880d681SAndroid Build Coastguard Worker .addReg(CondReg, getKillRegState(CondIsKill)).addImm(1);
2202*9880d681SAndroid Build Coastguard Worker }
2203*9880d681SAndroid Build Coastguard Worker
2204*9880d681SAndroid Build Coastguard Worker const Value *LHS = I->getOperand(1);
2205*9880d681SAndroid Build Coastguard Worker const Value *RHS = I->getOperand(2);
2206*9880d681SAndroid Build Coastguard Worker
2207*9880d681SAndroid Build Coastguard Worker unsigned LHSReg = getRegForValue(LHS);
2208*9880d681SAndroid Build Coastguard Worker bool LHSIsKill = hasTrivialKill(LHS);
2209*9880d681SAndroid Build Coastguard Worker
2210*9880d681SAndroid Build Coastguard Worker unsigned RHSReg = getRegForValue(RHS);
2211*9880d681SAndroid Build Coastguard Worker bool RHSIsKill = hasTrivialKill(RHS);
2212*9880d681SAndroid Build Coastguard Worker
2213*9880d681SAndroid Build Coastguard Worker if (!LHSReg || !RHSReg)
2214*9880d681SAndroid Build Coastguard Worker return false;
2215*9880d681SAndroid Build Coastguard Worker
2216*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = TLI.getRegClassFor(RetVT);
2217*9880d681SAndroid Build Coastguard Worker
2218*9880d681SAndroid Build Coastguard Worker unsigned ResultReg =
2219*9880d681SAndroid Build Coastguard Worker fastEmitInst_rri(Opc, RC, RHSReg, RHSIsKill, LHSReg, LHSIsKill, CC);
2220*9880d681SAndroid Build Coastguard Worker updateValueMap(I, ResultReg);
2221*9880d681SAndroid Build Coastguard Worker return true;
2222*9880d681SAndroid Build Coastguard Worker }
2223*9880d681SAndroid Build Coastguard Worker
X86SelectSelect(const Instruction * I)2224*9880d681SAndroid Build Coastguard Worker bool X86FastISel::X86SelectSelect(const Instruction *I) {
2225*9880d681SAndroid Build Coastguard Worker MVT RetVT;
2226*9880d681SAndroid Build Coastguard Worker if (!isTypeLegal(I->getType(), RetVT))
2227*9880d681SAndroid Build Coastguard Worker return false;
2228*9880d681SAndroid Build Coastguard Worker
2229*9880d681SAndroid Build Coastguard Worker // Check if we can fold the select.
2230*9880d681SAndroid Build Coastguard Worker if (const auto *CI = dyn_cast<CmpInst>(I->getOperand(0))) {
2231*9880d681SAndroid Build Coastguard Worker CmpInst::Predicate Predicate = optimizeCmpPredicate(CI);
2232*9880d681SAndroid Build Coastguard Worker const Value *Opnd = nullptr;
2233*9880d681SAndroid Build Coastguard Worker switch (Predicate) {
2234*9880d681SAndroid Build Coastguard Worker default: break;
2235*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_FALSE: Opnd = I->getOperand(2); break;
2236*9880d681SAndroid Build Coastguard Worker case CmpInst::FCMP_TRUE: Opnd = I->getOperand(1); break;
2237*9880d681SAndroid Build Coastguard Worker }
2238*9880d681SAndroid Build Coastguard Worker // No need for a select anymore - this is an unconditional move.
2239*9880d681SAndroid Build Coastguard Worker if (Opnd) {
2240*9880d681SAndroid Build Coastguard Worker unsigned OpReg = getRegForValue(Opnd);
2241*9880d681SAndroid Build Coastguard Worker if (OpReg == 0)
2242*9880d681SAndroid Build Coastguard Worker return false;
2243*9880d681SAndroid Build Coastguard Worker bool OpIsKill = hasTrivialKill(Opnd);
2244*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = TLI.getRegClassFor(RetVT);
2245*9880d681SAndroid Build Coastguard Worker unsigned ResultReg = createResultReg(RC);
2246*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2247*9880d681SAndroid Build Coastguard Worker TII.get(TargetOpcode::COPY), ResultReg)
2248*9880d681SAndroid Build Coastguard Worker .addReg(OpReg, getKillRegState(OpIsKill));
2249*9880d681SAndroid Build Coastguard Worker updateValueMap(I, ResultReg);
2250*9880d681SAndroid Build Coastguard Worker return true;
2251*9880d681SAndroid Build Coastguard Worker }
2252*9880d681SAndroid Build Coastguard Worker }
2253*9880d681SAndroid Build Coastguard Worker
2254*9880d681SAndroid Build Coastguard Worker // First try to use real conditional move instructions.
2255*9880d681SAndroid Build Coastguard Worker if (X86FastEmitCMoveSelect(RetVT, I))
2256*9880d681SAndroid Build Coastguard Worker return true;
2257*9880d681SAndroid Build Coastguard Worker
2258*9880d681SAndroid Build Coastguard Worker // Try to use a sequence of SSE instructions to simulate a conditional move.
2259*9880d681SAndroid Build Coastguard Worker if (X86FastEmitSSESelect(RetVT, I))
2260*9880d681SAndroid Build Coastguard Worker return true;
2261*9880d681SAndroid Build Coastguard Worker
2262*9880d681SAndroid Build Coastguard Worker // Fall-back to pseudo conditional move instructions, which will be later
2263*9880d681SAndroid Build Coastguard Worker // converted to control-flow.
2264*9880d681SAndroid Build Coastguard Worker if (X86FastEmitPseudoSelect(RetVT, I))
2265*9880d681SAndroid Build Coastguard Worker return true;
2266*9880d681SAndroid Build Coastguard Worker
2267*9880d681SAndroid Build Coastguard Worker return false;
2268*9880d681SAndroid Build Coastguard Worker }
2269*9880d681SAndroid Build Coastguard Worker
X86SelectSIToFP(const Instruction * I)2270*9880d681SAndroid Build Coastguard Worker bool X86FastISel::X86SelectSIToFP(const Instruction *I) {
2271*9880d681SAndroid Build Coastguard Worker // The target-independent selection algorithm in FastISel already knows how
2272*9880d681SAndroid Build Coastguard Worker // to select a SINT_TO_FP if the target is SSE but not AVX.
2273*9880d681SAndroid Build Coastguard Worker // Early exit if the subtarget doesn't have AVX.
2274*9880d681SAndroid Build Coastguard Worker if (!Subtarget->hasAVX())
2275*9880d681SAndroid Build Coastguard Worker return false;
2276*9880d681SAndroid Build Coastguard Worker
2277*9880d681SAndroid Build Coastguard Worker if (!I->getOperand(0)->getType()->isIntegerTy(32))
2278*9880d681SAndroid Build Coastguard Worker return false;
2279*9880d681SAndroid Build Coastguard Worker
2280*9880d681SAndroid Build Coastguard Worker // Select integer to float/double conversion.
2281*9880d681SAndroid Build Coastguard Worker unsigned OpReg = getRegForValue(I->getOperand(0));
2282*9880d681SAndroid Build Coastguard Worker if (OpReg == 0)
2283*9880d681SAndroid Build Coastguard Worker return false;
2284*9880d681SAndroid Build Coastguard Worker
2285*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = nullptr;
2286*9880d681SAndroid Build Coastguard Worker unsigned Opcode;
2287*9880d681SAndroid Build Coastguard Worker
2288*9880d681SAndroid Build Coastguard Worker if (I->getType()->isDoubleTy()) {
2289*9880d681SAndroid Build Coastguard Worker // sitofp int -> double
2290*9880d681SAndroid Build Coastguard Worker Opcode = X86::VCVTSI2SDrr;
2291*9880d681SAndroid Build Coastguard Worker RC = &X86::FR64RegClass;
2292*9880d681SAndroid Build Coastguard Worker } else if (I->getType()->isFloatTy()) {
2293*9880d681SAndroid Build Coastguard Worker // sitofp int -> float
2294*9880d681SAndroid Build Coastguard Worker Opcode = X86::VCVTSI2SSrr;
2295*9880d681SAndroid Build Coastguard Worker RC = &X86::FR32RegClass;
2296*9880d681SAndroid Build Coastguard Worker } else
2297*9880d681SAndroid Build Coastguard Worker return false;
2298*9880d681SAndroid Build Coastguard Worker
2299*9880d681SAndroid Build Coastguard Worker unsigned ImplicitDefReg = createResultReg(RC);
2300*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2301*9880d681SAndroid Build Coastguard Worker TII.get(TargetOpcode::IMPLICIT_DEF), ImplicitDefReg);
2302*9880d681SAndroid Build Coastguard Worker unsigned ResultReg =
2303*9880d681SAndroid Build Coastguard Worker fastEmitInst_rr(Opcode, RC, ImplicitDefReg, true, OpReg, false);
2304*9880d681SAndroid Build Coastguard Worker updateValueMap(I, ResultReg);
2305*9880d681SAndroid Build Coastguard Worker return true;
2306*9880d681SAndroid Build Coastguard Worker }
2307*9880d681SAndroid Build Coastguard Worker
2308*9880d681SAndroid Build Coastguard Worker // Helper method used by X86SelectFPExt and X86SelectFPTrunc.
X86SelectFPExtOrFPTrunc(const Instruction * I,unsigned TargetOpc,const TargetRegisterClass * RC)2309*9880d681SAndroid Build Coastguard Worker bool X86FastISel::X86SelectFPExtOrFPTrunc(const Instruction *I,
2310*9880d681SAndroid Build Coastguard Worker unsigned TargetOpc,
2311*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC) {
2312*9880d681SAndroid Build Coastguard Worker assert((I->getOpcode() == Instruction::FPExt ||
2313*9880d681SAndroid Build Coastguard Worker I->getOpcode() == Instruction::FPTrunc) &&
2314*9880d681SAndroid Build Coastguard Worker "Instruction must be an FPExt or FPTrunc!");
2315*9880d681SAndroid Build Coastguard Worker
2316*9880d681SAndroid Build Coastguard Worker unsigned OpReg = getRegForValue(I->getOperand(0));
2317*9880d681SAndroid Build Coastguard Worker if (OpReg == 0)
2318*9880d681SAndroid Build Coastguard Worker return false;
2319*9880d681SAndroid Build Coastguard Worker
2320*9880d681SAndroid Build Coastguard Worker unsigned ResultReg = createResultReg(RC);
2321*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder MIB;
2322*9880d681SAndroid Build Coastguard Worker MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(TargetOpc),
2323*9880d681SAndroid Build Coastguard Worker ResultReg);
2324*9880d681SAndroid Build Coastguard Worker if (Subtarget->hasAVX())
2325*9880d681SAndroid Build Coastguard Worker MIB.addReg(OpReg);
2326*9880d681SAndroid Build Coastguard Worker MIB.addReg(OpReg);
2327*9880d681SAndroid Build Coastguard Worker updateValueMap(I, ResultReg);
2328*9880d681SAndroid Build Coastguard Worker return true;
2329*9880d681SAndroid Build Coastguard Worker }
2330*9880d681SAndroid Build Coastguard Worker
X86SelectFPExt(const Instruction * I)2331*9880d681SAndroid Build Coastguard Worker bool X86FastISel::X86SelectFPExt(const Instruction *I) {
2332*9880d681SAndroid Build Coastguard Worker if (X86ScalarSSEf64 && I->getType()->isDoubleTy() &&
2333*9880d681SAndroid Build Coastguard Worker I->getOperand(0)->getType()->isFloatTy()) {
2334*9880d681SAndroid Build Coastguard Worker // fpext from float to double.
2335*9880d681SAndroid Build Coastguard Worker unsigned Opc = Subtarget->hasAVX() ? X86::VCVTSS2SDrr : X86::CVTSS2SDrr;
2336*9880d681SAndroid Build Coastguard Worker return X86SelectFPExtOrFPTrunc(I, Opc, &X86::FR64RegClass);
2337*9880d681SAndroid Build Coastguard Worker }
2338*9880d681SAndroid Build Coastguard Worker
2339*9880d681SAndroid Build Coastguard Worker return false;
2340*9880d681SAndroid Build Coastguard Worker }
2341*9880d681SAndroid Build Coastguard Worker
X86SelectFPTrunc(const Instruction * I)2342*9880d681SAndroid Build Coastguard Worker bool X86FastISel::X86SelectFPTrunc(const Instruction *I) {
2343*9880d681SAndroid Build Coastguard Worker if (X86ScalarSSEf64 && I->getType()->isFloatTy() &&
2344*9880d681SAndroid Build Coastguard Worker I->getOperand(0)->getType()->isDoubleTy()) {
2345*9880d681SAndroid Build Coastguard Worker // fptrunc from double to float.
2346*9880d681SAndroid Build Coastguard Worker unsigned Opc = Subtarget->hasAVX() ? X86::VCVTSD2SSrr : X86::CVTSD2SSrr;
2347*9880d681SAndroid Build Coastguard Worker return X86SelectFPExtOrFPTrunc(I, Opc, &X86::FR32RegClass);
2348*9880d681SAndroid Build Coastguard Worker }
2349*9880d681SAndroid Build Coastguard Worker
2350*9880d681SAndroid Build Coastguard Worker return false;
2351*9880d681SAndroid Build Coastguard Worker }
2352*9880d681SAndroid Build Coastguard Worker
X86SelectTrunc(const Instruction * I)2353*9880d681SAndroid Build Coastguard Worker bool X86FastISel::X86SelectTrunc(const Instruction *I) {
2354*9880d681SAndroid Build Coastguard Worker EVT SrcVT = TLI.getValueType(DL, I->getOperand(0)->getType());
2355*9880d681SAndroid Build Coastguard Worker EVT DstVT = TLI.getValueType(DL, I->getType());
2356*9880d681SAndroid Build Coastguard Worker
2357*9880d681SAndroid Build Coastguard Worker // This code only handles truncation to byte.
2358*9880d681SAndroid Build Coastguard Worker if (DstVT != MVT::i8 && DstVT != MVT::i1)
2359*9880d681SAndroid Build Coastguard Worker return false;
2360*9880d681SAndroid Build Coastguard Worker if (!TLI.isTypeLegal(SrcVT))
2361*9880d681SAndroid Build Coastguard Worker return false;
2362*9880d681SAndroid Build Coastguard Worker
2363*9880d681SAndroid Build Coastguard Worker unsigned InputReg = getRegForValue(I->getOperand(0));
2364*9880d681SAndroid Build Coastguard Worker if (!InputReg)
2365*9880d681SAndroid Build Coastguard Worker // Unhandled operand. Halt "fast" selection and bail.
2366*9880d681SAndroid Build Coastguard Worker return false;
2367*9880d681SAndroid Build Coastguard Worker
2368*9880d681SAndroid Build Coastguard Worker if (SrcVT == MVT::i8) {
2369*9880d681SAndroid Build Coastguard Worker // Truncate from i8 to i1; no code needed.
2370*9880d681SAndroid Build Coastguard Worker updateValueMap(I, InputReg);
2371*9880d681SAndroid Build Coastguard Worker return true;
2372*9880d681SAndroid Build Coastguard Worker }
2373*9880d681SAndroid Build Coastguard Worker
2374*9880d681SAndroid Build Coastguard Worker bool KillInputReg = false;
2375*9880d681SAndroid Build Coastguard Worker if (!Subtarget->is64Bit()) {
2376*9880d681SAndroid Build Coastguard Worker // If we're on x86-32; we can't extract an i8 from a general register.
2377*9880d681SAndroid Build Coastguard Worker // First issue a copy to GR16_ABCD or GR32_ABCD.
2378*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *CopyRC =
2379*9880d681SAndroid Build Coastguard Worker (SrcVT == MVT::i16) ? &X86::GR16_ABCDRegClass : &X86::GR32_ABCDRegClass;
2380*9880d681SAndroid Build Coastguard Worker unsigned CopyReg = createResultReg(CopyRC);
2381*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2382*9880d681SAndroid Build Coastguard Worker TII.get(TargetOpcode::COPY), CopyReg).addReg(InputReg);
2383*9880d681SAndroid Build Coastguard Worker InputReg = CopyReg;
2384*9880d681SAndroid Build Coastguard Worker KillInputReg = true;
2385*9880d681SAndroid Build Coastguard Worker }
2386*9880d681SAndroid Build Coastguard Worker
2387*9880d681SAndroid Build Coastguard Worker // Issue an extract_subreg.
2388*9880d681SAndroid Build Coastguard Worker unsigned ResultReg = fastEmitInst_extractsubreg(MVT::i8,
2389*9880d681SAndroid Build Coastguard Worker InputReg, KillInputReg,
2390*9880d681SAndroid Build Coastguard Worker X86::sub_8bit);
2391*9880d681SAndroid Build Coastguard Worker if (!ResultReg)
2392*9880d681SAndroid Build Coastguard Worker return false;
2393*9880d681SAndroid Build Coastguard Worker
2394*9880d681SAndroid Build Coastguard Worker updateValueMap(I, ResultReg);
2395*9880d681SAndroid Build Coastguard Worker return true;
2396*9880d681SAndroid Build Coastguard Worker }
2397*9880d681SAndroid Build Coastguard Worker
IsMemcpySmall(uint64_t Len)2398*9880d681SAndroid Build Coastguard Worker bool X86FastISel::IsMemcpySmall(uint64_t Len) {
2399*9880d681SAndroid Build Coastguard Worker return Len <= (Subtarget->is64Bit() ? 32 : 16);
2400*9880d681SAndroid Build Coastguard Worker }
2401*9880d681SAndroid Build Coastguard Worker
TryEmitSmallMemcpy(X86AddressMode DestAM,X86AddressMode SrcAM,uint64_t Len)2402*9880d681SAndroid Build Coastguard Worker bool X86FastISel::TryEmitSmallMemcpy(X86AddressMode DestAM,
2403*9880d681SAndroid Build Coastguard Worker X86AddressMode SrcAM, uint64_t Len) {
2404*9880d681SAndroid Build Coastguard Worker
2405*9880d681SAndroid Build Coastguard Worker // Make sure we don't bloat code by inlining very large memcpy's.
2406*9880d681SAndroid Build Coastguard Worker if (!IsMemcpySmall(Len))
2407*9880d681SAndroid Build Coastguard Worker return false;
2408*9880d681SAndroid Build Coastguard Worker
2409*9880d681SAndroid Build Coastguard Worker bool i64Legal = Subtarget->is64Bit();
2410*9880d681SAndroid Build Coastguard Worker
2411*9880d681SAndroid Build Coastguard Worker // We don't care about alignment here since we just emit integer accesses.
2412*9880d681SAndroid Build Coastguard Worker while (Len) {
2413*9880d681SAndroid Build Coastguard Worker MVT VT;
2414*9880d681SAndroid Build Coastguard Worker if (Len >= 8 && i64Legal)
2415*9880d681SAndroid Build Coastguard Worker VT = MVT::i64;
2416*9880d681SAndroid Build Coastguard Worker else if (Len >= 4)
2417*9880d681SAndroid Build Coastguard Worker VT = MVT::i32;
2418*9880d681SAndroid Build Coastguard Worker else if (Len >= 2)
2419*9880d681SAndroid Build Coastguard Worker VT = MVT::i16;
2420*9880d681SAndroid Build Coastguard Worker else
2421*9880d681SAndroid Build Coastguard Worker VT = MVT::i8;
2422*9880d681SAndroid Build Coastguard Worker
2423*9880d681SAndroid Build Coastguard Worker unsigned Reg;
2424*9880d681SAndroid Build Coastguard Worker bool RV = X86FastEmitLoad(VT, SrcAM, nullptr, Reg);
2425*9880d681SAndroid Build Coastguard Worker RV &= X86FastEmitStore(VT, Reg, /*Kill=*/true, DestAM);
2426*9880d681SAndroid Build Coastguard Worker assert(RV && "Failed to emit load or store??");
2427*9880d681SAndroid Build Coastguard Worker
2428*9880d681SAndroid Build Coastguard Worker unsigned Size = VT.getSizeInBits()/8;
2429*9880d681SAndroid Build Coastguard Worker Len -= Size;
2430*9880d681SAndroid Build Coastguard Worker DestAM.Disp += Size;
2431*9880d681SAndroid Build Coastguard Worker SrcAM.Disp += Size;
2432*9880d681SAndroid Build Coastguard Worker }
2433*9880d681SAndroid Build Coastguard Worker
2434*9880d681SAndroid Build Coastguard Worker return true;
2435*9880d681SAndroid Build Coastguard Worker }
2436*9880d681SAndroid Build Coastguard Worker
fastLowerIntrinsicCall(const IntrinsicInst * II)2437*9880d681SAndroid Build Coastguard Worker bool X86FastISel::fastLowerIntrinsicCall(const IntrinsicInst *II) {
2438*9880d681SAndroid Build Coastguard Worker // FIXME: Handle more intrinsics.
2439*9880d681SAndroid Build Coastguard Worker switch (II->getIntrinsicID()) {
2440*9880d681SAndroid Build Coastguard Worker default: return false;
2441*9880d681SAndroid Build Coastguard Worker case Intrinsic::convert_from_fp16:
2442*9880d681SAndroid Build Coastguard Worker case Intrinsic::convert_to_fp16: {
2443*9880d681SAndroid Build Coastguard Worker if (Subtarget->useSoftFloat() || !Subtarget->hasF16C())
2444*9880d681SAndroid Build Coastguard Worker return false;
2445*9880d681SAndroid Build Coastguard Worker
2446*9880d681SAndroid Build Coastguard Worker const Value *Op = II->getArgOperand(0);
2447*9880d681SAndroid Build Coastguard Worker unsigned InputReg = getRegForValue(Op);
2448*9880d681SAndroid Build Coastguard Worker if (InputReg == 0)
2449*9880d681SAndroid Build Coastguard Worker return false;
2450*9880d681SAndroid Build Coastguard Worker
2451*9880d681SAndroid Build Coastguard Worker // F16C only allows converting from float to half and from half to float.
2452*9880d681SAndroid Build Coastguard Worker bool IsFloatToHalf = II->getIntrinsicID() == Intrinsic::convert_to_fp16;
2453*9880d681SAndroid Build Coastguard Worker if (IsFloatToHalf) {
2454*9880d681SAndroid Build Coastguard Worker if (!Op->getType()->isFloatTy())
2455*9880d681SAndroid Build Coastguard Worker return false;
2456*9880d681SAndroid Build Coastguard Worker } else {
2457*9880d681SAndroid Build Coastguard Worker if (!II->getType()->isFloatTy())
2458*9880d681SAndroid Build Coastguard Worker return false;
2459*9880d681SAndroid Build Coastguard Worker }
2460*9880d681SAndroid Build Coastguard Worker
2461*9880d681SAndroid Build Coastguard Worker unsigned ResultReg = 0;
2462*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = TLI.getRegClassFor(MVT::v8i16);
2463*9880d681SAndroid Build Coastguard Worker if (IsFloatToHalf) {
2464*9880d681SAndroid Build Coastguard Worker // 'InputReg' is implicitly promoted from register class FR32 to
2465*9880d681SAndroid Build Coastguard Worker // register class VR128 by method 'constrainOperandRegClass' which is
2466*9880d681SAndroid Build Coastguard Worker // directly called by 'fastEmitInst_ri'.
2467*9880d681SAndroid Build Coastguard Worker // Instruction VCVTPS2PHrr takes an extra immediate operand which is
2468*9880d681SAndroid Build Coastguard Worker // used to provide rounding control: use MXCSR.RC, encoded as 0b100.
2469*9880d681SAndroid Build Coastguard Worker // It's consistent with the other FP instructions, which are usually
2470*9880d681SAndroid Build Coastguard Worker // controlled by MXCSR.
2471*9880d681SAndroid Build Coastguard Worker InputReg = fastEmitInst_ri(X86::VCVTPS2PHrr, RC, InputReg, false, 4);
2472*9880d681SAndroid Build Coastguard Worker
2473*9880d681SAndroid Build Coastguard Worker // Move the lower 32-bits of ResultReg to another register of class GR32.
2474*9880d681SAndroid Build Coastguard Worker ResultReg = createResultReg(&X86::GR32RegClass);
2475*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2476*9880d681SAndroid Build Coastguard Worker TII.get(X86::VMOVPDI2DIrr), ResultReg)
2477*9880d681SAndroid Build Coastguard Worker .addReg(InputReg, RegState::Kill);
2478*9880d681SAndroid Build Coastguard Worker
2479*9880d681SAndroid Build Coastguard Worker // The result value is in the lower 16-bits of ResultReg.
2480*9880d681SAndroid Build Coastguard Worker unsigned RegIdx = X86::sub_16bit;
2481*9880d681SAndroid Build Coastguard Worker ResultReg = fastEmitInst_extractsubreg(MVT::i16, ResultReg, true, RegIdx);
2482*9880d681SAndroid Build Coastguard Worker } else {
2483*9880d681SAndroid Build Coastguard Worker assert(Op->getType()->isIntegerTy(16) && "Expected a 16-bit integer!");
2484*9880d681SAndroid Build Coastguard Worker // Explicitly sign-extend the input to 32-bit.
2485*9880d681SAndroid Build Coastguard Worker InputReg = fastEmit_r(MVT::i16, MVT::i32, ISD::SIGN_EXTEND, InputReg,
2486*9880d681SAndroid Build Coastguard Worker /*Kill=*/false);
2487*9880d681SAndroid Build Coastguard Worker
2488*9880d681SAndroid Build Coastguard Worker // The following SCALAR_TO_VECTOR will be expanded into a VMOVDI2PDIrr.
2489*9880d681SAndroid Build Coastguard Worker InputReg = fastEmit_r(MVT::i32, MVT::v4i32, ISD::SCALAR_TO_VECTOR,
2490*9880d681SAndroid Build Coastguard Worker InputReg, /*Kill=*/true);
2491*9880d681SAndroid Build Coastguard Worker
2492*9880d681SAndroid Build Coastguard Worker InputReg = fastEmitInst_r(X86::VCVTPH2PSrr, RC, InputReg, /*Kill=*/true);
2493*9880d681SAndroid Build Coastguard Worker
2494*9880d681SAndroid Build Coastguard Worker // The result value is in the lower 32-bits of ResultReg.
2495*9880d681SAndroid Build Coastguard Worker // Emit an explicit copy from register class VR128 to register class FR32.
2496*9880d681SAndroid Build Coastguard Worker ResultReg = createResultReg(&X86::FR32RegClass);
2497*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2498*9880d681SAndroid Build Coastguard Worker TII.get(TargetOpcode::COPY), ResultReg)
2499*9880d681SAndroid Build Coastguard Worker .addReg(InputReg, RegState::Kill);
2500*9880d681SAndroid Build Coastguard Worker }
2501*9880d681SAndroid Build Coastguard Worker
2502*9880d681SAndroid Build Coastguard Worker updateValueMap(II, ResultReg);
2503*9880d681SAndroid Build Coastguard Worker return true;
2504*9880d681SAndroid Build Coastguard Worker }
2505*9880d681SAndroid Build Coastguard Worker case Intrinsic::frameaddress: {
2506*9880d681SAndroid Build Coastguard Worker MachineFunction *MF = FuncInfo.MF;
2507*9880d681SAndroid Build Coastguard Worker if (MF->getTarget().getMCAsmInfo()->usesWindowsCFI())
2508*9880d681SAndroid Build Coastguard Worker return false;
2509*9880d681SAndroid Build Coastguard Worker
2510*9880d681SAndroid Build Coastguard Worker Type *RetTy = II->getCalledFunction()->getReturnType();
2511*9880d681SAndroid Build Coastguard Worker
2512*9880d681SAndroid Build Coastguard Worker MVT VT;
2513*9880d681SAndroid Build Coastguard Worker if (!isTypeLegal(RetTy, VT))
2514*9880d681SAndroid Build Coastguard Worker return false;
2515*9880d681SAndroid Build Coastguard Worker
2516*9880d681SAndroid Build Coastguard Worker unsigned Opc;
2517*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = nullptr;
2518*9880d681SAndroid Build Coastguard Worker
2519*9880d681SAndroid Build Coastguard Worker switch (VT.SimpleTy) {
2520*9880d681SAndroid Build Coastguard Worker default: llvm_unreachable("Invalid result type for frameaddress.");
2521*9880d681SAndroid Build Coastguard Worker case MVT::i32: Opc = X86::MOV32rm; RC = &X86::GR32RegClass; break;
2522*9880d681SAndroid Build Coastguard Worker case MVT::i64: Opc = X86::MOV64rm; RC = &X86::GR64RegClass; break;
2523*9880d681SAndroid Build Coastguard Worker }
2524*9880d681SAndroid Build Coastguard Worker
2525*9880d681SAndroid Build Coastguard Worker // This needs to be set before we call getPtrSizedFrameRegister, otherwise
2526*9880d681SAndroid Build Coastguard Worker // we get the wrong frame register.
2527*9880d681SAndroid Build Coastguard Worker MachineFrameInfo *MFI = MF->getFrameInfo();
2528*9880d681SAndroid Build Coastguard Worker MFI->setFrameAddressIsTaken(true);
2529*9880d681SAndroid Build Coastguard Worker
2530*9880d681SAndroid Build Coastguard Worker const X86RegisterInfo *RegInfo = Subtarget->getRegisterInfo();
2531*9880d681SAndroid Build Coastguard Worker unsigned FrameReg = RegInfo->getPtrSizedFrameRegister(*MF);
2532*9880d681SAndroid Build Coastguard Worker assert(((FrameReg == X86::RBP && VT == MVT::i64) ||
2533*9880d681SAndroid Build Coastguard Worker (FrameReg == X86::EBP && VT == MVT::i32)) &&
2534*9880d681SAndroid Build Coastguard Worker "Invalid Frame Register!");
2535*9880d681SAndroid Build Coastguard Worker
2536*9880d681SAndroid Build Coastguard Worker // Always make a copy of the frame register to to a vreg first, so that we
2537*9880d681SAndroid Build Coastguard Worker // never directly reference the frame register (the TwoAddressInstruction-
2538*9880d681SAndroid Build Coastguard Worker // Pass doesn't like that).
2539*9880d681SAndroid Build Coastguard Worker unsigned SrcReg = createResultReg(RC);
2540*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2541*9880d681SAndroid Build Coastguard Worker TII.get(TargetOpcode::COPY), SrcReg).addReg(FrameReg);
2542*9880d681SAndroid Build Coastguard Worker
2543*9880d681SAndroid Build Coastguard Worker // Now recursively load from the frame address.
2544*9880d681SAndroid Build Coastguard Worker // movq (%rbp), %rax
2545*9880d681SAndroid Build Coastguard Worker // movq (%rax), %rax
2546*9880d681SAndroid Build Coastguard Worker // movq (%rax), %rax
2547*9880d681SAndroid Build Coastguard Worker // ...
2548*9880d681SAndroid Build Coastguard Worker unsigned DestReg;
2549*9880d681SAndroid Build Coastguard Worker unsigned Depth = cast<ConstantInt>(II->getOperand(0))->getZExtValue();
2550*9880d681SAndroid Build Coastguard Worker while (Depth--) {
2551*9880d681SAndroid Build Coastguard Worker DestReg = createResultReg(RC);
2552*9880d681SAndroid Build Coastguard Worker addDirectMem(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2553*9880d681SAndroid Build Coastguard Worker TII.get(Opc), DestReg), SrcReg);
2554*9880d681SAndroid Build Coastguard Worker SrcReg = DestReg;
2555*9880d681SAndroid Build Coastguard Worker }
2556*9880d681SAndroid Build Coastguard Worker
2557*9880d681SAndroid Build Coastguard Worker updateValueMap(II, SrcReg);
2558*9880d681SAndroid Build Coastguard Worker return true;
2559*9880d681SAndroid Build Coastguard Worker }
2560*9880d681SAndroid Build Coastguard Worker case Intrinsic::memcpy: {
2561*9880d681SAndroid Build Coastguard Worker const MemCpyInst *MCI = cast<MemCpyInst>(II);
2562*9880d681SAndroid Build Coastguard Worker // Don't handle volatile or variable length memcpys.
2563*9880d681SAndroid Build Coastguard Worker if (MCI->isVolatile())
2564*9880d681SAndroid Build Coastguard Worker return false;
2565*9880d681SAndroid Build Coastguard Worker
2566*9880d681SAndroid Build Coastguard Worker if (isa<ConstantInt>(MCI->getLength())) {
2567*9880d681SAndroid Build Coastguard Worker // Small memcpy's are common enough that we want to do them
2568*9880d681SAndroid Build Coastguard Worker // without a call if possible.
2569*9880d681SAndroid Build Coastguard Worker uint64_t Len = cast<ConstantInt>(MCI->getLength())->getZExtValue();
2570*9880d681SAndroid Build Coastguard Worker if (IsMemcpySmall(Len)) {
2571*9880d681SAndroid Build Coastguard Worker X86AddressMode DestAM, SrcAM;
2572*9880d681SAndroid Build Coastguard Worker if (!X86SelectAddress(MCI->getRawDest(), DestAM) ||
2573*9880d681SAndroid Build Coastguard Worker !X86SelectAddress(MCI->getRawSource(), SrcAM))
2574*9880d681SAndroid Build Coastguard Worker return false;
2575*9880d681SAndroid Build Coastguard Worker TryEmitSmallMemcpy(DestAM, SrcAM, Len);
2576*9880d681SAndroid Build Coastguard Worker return true;
2577*9880d681SAndroid Build Coastguard Worker }
2578*9880d681SAndroid Build Coastguard Worker }
2579*9880d681SAndroid Build Coastguard Worker
2580*9880d681SAndroid Build Coastguard Worker unsigned SizeWidth = Subtarget->is64Bit() ? 64 : 32;
2581*9880d681SAndroid Build Coastguard Worker if (!MCI->getLength()->getType()->isIntegerTy(SizeWidth))
2582*9880d681SAndroid Build Coastguard Worker return false;
2583*9880d681SAndroid Build Coastguard Worker
2584*9880d681SAndroid Build Coastguard Worker if (MCI->getSourceAddressSpace() > 255 || MCI->getDestAddressSpace() > 255)
2585*9880d681SAndroid Build Coastguard Worker return false;
2586*9880d681SAndroid Build Coastguard Worker
2587*9880d681SAndroid Build Coastguard Worker return lowerCallTo(II, "memcpy", II->getNumArgOperands() - 2);
2588*9880d681SAndroid Build Coastguard Worker }
2589*9880d681SAndroid Build Coastguard Worker case Intrinsic::memset: {
2590*9880d681SAndroid Build Coastguard Worker const MemSetInst *MSI = cast<MemSetInst>(II);
2591*9880d681SAndroid Build Coastguard Worker
2592*9880d681SAndroid Build Coastguard Worker if (MSI->isVolatile())
2593*9880d681SAndroid Build Coastguard Worker return false;
2594*9880d681SAndroid Build Coastguard Worker
2595*9880d681SAndroid Build Coastguard Worker unsigned SizeWidth = Subtarget->is64Bit() ? 64 : 32;
2596*9880d681SAndroid Build Coastguard Worker if (!MSI->getLength()->getType()->isIntegerTy(SizeWidth))
2597*9880d681SAndroid Build Coastguard Worker return false;
2598*9880d681SAndroid Build Coastguard Worker
2599*9880d681SAndroid Build Coastguard Worker if (MSI->getDestAddressSpace() > 255)
2600*9880d681SAndroid Build Coastguard Worker return false;
2601*9880d681SAndroid Build Coastguard Worker
2602*9880d681SAndroid Build Coastguard Worker return lowerCallTo(II, "memset", II->getNumArgOperands() - 2);
2603*9880d681SAndroid Build Coastguard Worker }
2604*9880d681SAndroid Build Coastguard Worker case Intrinsic::stackprotector: {
2605*9880d681SAndroid Build Coastguard Worker // Emit code to store the stack guard onto the stack.
2606*9880d681SAndroid Build Coastguard Worker EVT PtrTy = TLI.getPointerTy(DL);
2607*9880d681SAndroid Build Coastguard Worker
2608*9880d681SAndroid Build Coastguard Worker const Value *Op1 = II->getArgOperand(0); // The guard's value.
2609*9880d681SAndroid Build Coastguard Worker const AllocaInst *Slot = cast<AllocaInst>(II->getArgOperand(1));
2610*9880d681SAndroid Build Coastguard Worker
2611*9880d681SAndroid Build Coastguard Worker MFI.setStackProtectorIndex(FuncInfo.StaticAllocaMap[Slot]);
2612*9880d681SAndroid Build Coastguard Worker
2613*9880d681SAndroid Build Coastguard Worker // Grab the frame index.
2614*9880d681SAndroid Build Coastguard Worker X86AddressMode AM;
2615*9880d681SAndroid Build Coastguard Worker if (!X86SelectAddress(Slot, AM)) return false;
2616*9880d681SAndroid Build Coastguard Worker if (!X86FastEmitStore(PtrTy, Op1, AM)) return false;
2617*9880d681SAndroid Build Coastguard Worker return true;
2618*9880d681SAndroid Build Coastguard Worker }
2619*9880d681SAndroid Build Coastguard Worker case Intrinsic::dbg_declare: {
2620*9880d681SAndroid Build Coastguard Worker const DbgDeclareInst *DI = cast<DbgDeclareInst>(II);
2621*9880d681SAndroid Build Coastguard Worker X86AddressMode AM;
2622*9880d681SAndroid Build Coastguard Worker assert(DI->getAddress() && "Null address should be checked earlier!");
2623*9880d681SAndroid Build Coastguard Worker if (!X86SelectAddress(DI->getAddress(), AM))
2624*9880d681SAndroid Build Coastguard Worker return false;
2625*9880d681SAndroid Build Coastguard Worker const MCInstrDesc &II = TII.get(TargetOpcode::DBG_VALUE);
2626*9880d681SAndroid Build Coastguard Worker // FIXME may need to add RegState::Debug to any registers produced,
2627*9880d681SAndroid Build Coastguard Worker // although ESP/EBP should be the only ones at the moment.
2628*9880d681SAndroid Build Coastguard Worker assert(DI->getVariable()->isValidLocationForIntrinsic(DbgLoc) &&
2629*9880d681SAndroid Build Coastguard Worker "Expected inlined-at fields to agree");
2630*9880d681SAndroid Build Coastguard Worker addFullAddress(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II), AM)
2631*9880d681SAndroid Build Coastguard Worker .addImm(0)
2632*9880d681SAndroid Build Coastguard Worker .addMetadata(DI->getVariable())
2633*9880d681SAndroid Build Coastguard Worker .addMetadata(DI->getExpression());
2634*9880d681SAndroid Build Coastguard Worker return true;
2635*9880d681SAndroid Build Coastguard Worker }
2636*9880d681SAndroid Build Coastguard Worker case Intrinsic::trap: {
2637*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::TRAP));
2638*9880d681SAndroid Build Coastguard Worker return true;
2639*9880d681SAndroid Build Coastguard Worker }
2640*9880d681SAndroid Build Coastguard Worker case Intrinsic::sqrt: {
2641*9880d681SAndroid Build Coastguard Worker if (!Subtarget->hasSSE1())
2642*9880d681SAndroid Build Coastguard Worker return false;
2643*9880d681SAndroid Build Coastguard Worker
2644*9880d681SAndroid Build Coastguard Worker Type *RetTy = II->getCalledFunction()->getReturnType();
2645*9880d681SAndroid Build Coastguard Worker
2646*9880d681SAndroid Build Coastguard Worker MVT VT;
2647*9880d681SAndroid Build Coastguard Worker if (!isTypeLegal(RetTy, VT))
2648*9880d681SAndroid Build Coastguard Worker return false;
2649*9880d681SAndroid Build Coastguard Worker
2650*9880d681SAndroid Build Coastguard Worker // Unfortunately we can't use fastEmit_r, because the AVX version of FSQRT
2651*9880d681SAndroid Build Coastguard Worker // is not generated by FastISel yet.
2652*9880d681SAndroid Build Coastguard Worker // FIXME: Update this code once tablegen can handle it.
2653*9880d681SAndroid Build Coastguard Worker static const uint16_t SqrtOpc[2][2] = {
2654*9880d681SAndroid Build Coastguard Worker {X86::SQRTSSr, X86::VSQRTSSr},
2655*9880d681SAndroid Build Coastguard Worker {X86::SQRTSDr, X86::VSQRTSDr}
2656*9880d681SAndroid Build Coastguard Worker };
2657*9880d681SAndroid Build Coastguard Worker bool HasAVX = Subtarget->hasAVX();
2658*9880d681SAndroid Build Coastguard Worker unsigned Opc;
2659*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC;
2660*9880d681SAndroid Build Coastguard Worker switch (VT.SimpleTy) {
2661*9880d681SAndroid Build Coastguard Worker default: return false;
2662*9880d681SAndroid Build Coastguard Worker case MVT::f32: Opc = SqrtOpc[0][HasAVX]; RC = &X86::FR32RegClass; break;
2663*9880d681SAndroid Build Coastguard Worker case MVT::f64: Opc = SqrtOpc[1][HasAVX]; RC = &X86::FR64RegClass; break;
2664*9880d681SAndroid Build Coastguard Worker }
2665*9880d681SAndroid Build Coastguard Worker
2666*9880d681SAndroid Build Coastguard Worker const Value *SrcVal = II->getArgOperand(0);
2667*9880d681SAndroid Build Coastguard Worker unsigned SrcReg = getRegForValue(SrcVal);
2668*9880d681SAndroid Build Coastguard Worker
2669*9880d681SAndroid Build Coastguard Worker if (SrcReg == 0)
2670*9880d681SAndroid Build Coastguard Worker return false;
2671*9880d681SAndroid Build Coastguard Worker
2672*9880d681SAndroid Build Coastguard Worker unsigned ImplicitDefReg = 0;
2673*9880d681SAndroid Build Coastguard Worker if (HasAVX) {
2674*9880d681SAndroid Build Coastguard Worker ImplicitDefReg = createResultReg(RC);
2675*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2676*9880d681SAndroid Build Coastguard Worker TII.get(TargetOpcode::IMPLICIT_DEF), ImplicitDefReg);
2677*9880d681SAndroid Build Coastguard Worker }
2678*9880d681SAndroid Build Coastguard Worker
2679*9880d681SAndroid Build Coastguard Worker unsigned ResultReg = createResultReg(RC);
2680*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder MIB;
2681*9880d681SAndroid Build Coastguard Worker MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc),
2682*9880d681SAndroid Build Coastguard Worker ResultReg);
2683*9880d681SAndroid Build Coastguard Worker
2684*9880d681SAndroid Build Coastguard Worker if (ImplicitDefReg)
2685*9880d681SAndroid Build Coastguard Worker MIB.addReg(ImplicitDefReg);
2686*9880d681SAndroid Build Coastguard Worker
2687*9880d681SAndroid Build Coastguard Worker MIB.addReg(SrcReg);
2688*9880d681SAndroid Build Coastguard Worker
2689*9880d681SAndroid Build Coastguard Worker updateValueMap(II, ResultReg);
2690*9880d681SAndroid Build Coastguard Worker return true;
2691*9880d681SAndroid Build Coastguard Worker }
2692*9880d681SAndroid Build Coastguard Worker case Intrinsic::sadd_with_overflow:
2693*9880d681SAndroid Build Coastguard Worker case Intrinsic::uadd_with_overflow:
2694*9880d681SAndroid Build Coastguard Worker case Intrinsic::ssub_with_overflow:
2695*9880d681SAndroid Build Coastguard Worker case Intrinsic::usub_with_overflow:
2696*9880d681SAndroid Build Coastguard Worker case Intrinsic::smul_with_overflow:
2697*9880d681SAndroid Build Coastguard Worker case Intrinsic::umul_with_overflow: {
2698*9880d681SAndroid Build Coastguard Worker // This implements the basic lowering of the xalu with overflow intrinsics
2699*9880d681SAndroid Build Coastguard Worker // into add/sub/mul followed by either seto or setb.
2700*9880d681SAndroid Build Coastguard Worker const Function *Callee = II->getCalledFunction();
2701*9880d681SAndroid Build Coastguard Worker auto *Ty = cast<StructType>(Callee->getReturnType());
2702*9880d681SAndroid Build Coastguard Worker Type *RetTy = Ty->getTypeAtIndex(0U);
2703*9880d681SAndroid Build Coastguard Worker Type *CondTy = Ty->getTypeAtIndex(1);
2704*9880d681SAndroid Build Coastguard Worker
2705*9880d681SAndroid Build Coastguard Worker MVT VT;
2706*9880d681SAndroid Build Coastguard Worker if (!isTypeLegal(RetTy, VT))
2707*9880d681SAndroid Build Coastguard Worker return false;
2708*9880d681SAndroid Build Coastguard Worker
2709*9880d681SAndroid Build Coastguard Worker if (VT < MVT::i8 || VT > MVT::i64)
2710*9880d681SAndroid Build Coastguard Worker return false;
2711*9880d681SAndroid Build Coastguard Worker
2712*9880d681SAndroid Build Coastguard Worker const Value *LHS = II->getArgOperand(0);
2713*9880d681SAndroid Build Coastguard Worker const Value *RHS = II->getArgOperand(1);
2714*9880d681SAndroid Build Coastguard Worker
2715*9880d681SAndroid Build Coastguard Worker // Canonicalize immediate to the RHS.
2716*9880d681SAndroid Build Coastguard Worker if (isa<ConstantInt>(LHS) && !isa<ConstantInt>(RHS) &&
2717*9880d681SAndroid Build Coastguard Worker isCommutativeIntrinsic(II))
2718*9880d681SAndroid Build Coastguard Worker std::swap(LHS, RHS);
2719*9880d681SAndroid Build Coastguard Worker
2720*9880d681SAndroid Build Coastguard Worker bool UseIncDec = false;
2721*9880d681SAndroid Build Coastguard Worker if (isa<ConstantInt>(RHS) && cast<ConstantInt>(RHS)->isOne())
2722*9880d681SAndroid Build Coastguard Worker UseIncDec = true;
2723*9880d681SAndroid Build Coastguard Worker
2724*9880d681SAndroid Build Coastguard Worker unsigned BaseOpc, CondOpc;
2725*9880d681SAndroid Build Coastguard Worker switch (II->getIntrinsicID()) {
2726*9880d681SAndroid Build Coastguard Worker default: llvm_unreachable("Unexpected intrinsic!");
2727*9880d681SAndroid Build Coastguard Worker case Intrinsic::sadd_with_overflow:
2728*9880d681SAndroid Build Coastguard Worker BaseOpc = UseIncDec ? unsigned(X86ISD::INC) : unsigned(ISD::ADD);
2729*9880d681SAndroid Build Coastguard Worker CondOpc = X86::SETOr;
2730*9880d681SAndroid Build Coastguard Worker break;
2731*9880d681SAndroid Build Coastguard Worker case Intrinsic::uadd_with_overflow:
2732*9880d681SAndroid Build Coastguard Worker BaseOpc = ISD::ADD; CondOpc = X86::SETBr; break;
2733*9880d681SAndroid Build Coastguard Worker case Intrinsic::ssub_with_overflow:
2734*9880d681SAndroid Build Coastguard Worker BaseOpc = UseIncDec ? unsigned(X86ISD::DEC) : unsigned(ISD::SUB);
2735*9880d681SAndroid Build Coastguard Worker CondOpc = X86::SETOr;
2736*9880d681SAndroid Build Coastguard Worker break;
2737*9880d681SAndroid Build Coastguard Worker case Intrinsic::usub_with_overflow:
2738*9880d681SAndroid Build Coastguard Worker BaseOpc = ISD::SUB; CondOpc = X86::SETBr; break;
2739*9880d681SAndroid Build Coastguard Worker case Intrinsic::smul_with_overflow:
2740*9880d681SAndroid Build Coastguard Worker BaseOpc = X86ISD::SMUL; CondOpc = X86::SETOr; break;
2741*9880d681SAndroid Build Coastguard Worker case Intrinsic::umul_with_overflow:
2742*9880d681SAndroid Build Coastguard Worker BaseOpc = X86ISD::UMUL; CondOpc = X86::SETOr; break;
2743*9880d681SAndroid Build Coastguard Worker }
2744*9880d681SAndroid Build Coastguard Worker
2745*9880d681SAndroid Build Coastguard Worker unsigned LHSReg = getRegForValue(LHS);
2746*9880d681SAndroid Build Coastguard Worker if (LHSReg == 0)
2747*9880d681SAndroid Build Coastguard Worker return false;
2748*9880d681SAndroid Build Coastguard Worker bool LHSIsKill = hasTrivialKill(LHS);
2749*9880d681SAndroid Build Coastguard Worker
2750*9880d681SAndroid Build Coastguard Worker unsigned ResultReg = 0;
2751*9880d681SAndroid Build Coastguard Worker // Check if we have an immediate version.
2752*9880d681SAndroid Build Coastguard Worker if (const auto *CI = dyn_cast<ConstantInt>(RHS)) {
2753*9880d681SAndroid Build Coastguard Worker static const uint16_t Opc[2][4] = {
2754*9880d681SAndroid Build Coastguard Worker { X86::INC8r, X86::INC16r, X86::INC32r, X86::INC64r },
2755*9880d681SAndroid Build Coastguard Worker { X86::DEC8r, X86::DEC16r, X86::DEC32r, X86::DEC64r }
2756*9880d681SAndroid Build Coastguard Worker };
2757*9880d681SAndroid Build Coastguard Worker
2758*9880d681SAndroid Build Coastguard Worker if (BaseOpc == X86ISD::INC || BaseOpc == X86ISD::DEC) {
2759*9880d681SAndroid Build Coastguard Worker ResultReg = createResultReg(TLI.getRegClassFor(VT));
2760*9880d681SAndroid Build Coastguard Worker bool IsDec = BaseOpc == X86ISD::DEC;
2761*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2762*9880d681SAndroid Build Coastguard Worker TII.get(Opc[IsDec][VT.SimpleTy-MVT::i8]), ResultReg)
2763*9880d681SAndroid Build Coastguard Worker .addReg(LHSReg, getKillRegState(LHSIsKill));
2764*9880d681SAndroid Build Coastguard Worker } else
2765*9880d681SAndroid Build Coastguard Worker ResultReg = fastEmit_ri(VT, VT, BaseOpc, LHSReg, LHSIsKill,
2766*9880d681SAndroid Build Coastguard Worker CI->getZExtValue());
2767*9880d681SAndroid Build Coastguard Worker }
2768*9880d681SAndroid Build Coastguard Worker
2769*9880d681SAndroid Build Coastguard Worker unsigned RHSReg;
2770*9880d681SAndroid Build Coastguard Worker bool RHSIsKill;
2771*9880d681SAndroid Build Coastguard Worker if (!ResultReg) {
2772*9880d681SAndroid Build Coastguard Worker RHSReg = getRegForValue(RHS);
2773*9880d681SAndroid Build Coastguard Worker if (RHSReg == 0)
2774*9880d681SAndroid Build Coastguard Worker return false;
2775*9880d681SAndroid Build Coastguard Worker RHSIsKill = hasTrivialKill(RHS);
2776*9880d681SAndroid Build Coastguard Worker ResultReg = fastEmit_rr(VT, VT, BaseOpc, LHSReg, LHSIsKill, RHSReg,
2777*9880d681SAndroid Build Coastguard Worker RHSIsKill);
2778*9880d681SAndroid Build Coastguard Worker }
2779*9880d681SAndroid Build Coastguard Worker
2780*9880d681SAndroid Build Coastguard Worker // FastISel doesn't have a pattern for all X86::MUL*r and X86::IMUL*r. Emit
2781*9880d681SAndroid Build Coastguard Worker // it manually.
2782*9880d681SAndroid Build Coastguard Worker if (BaseOpc == X86ISD::UMUL && !ResultReg) {
2783*9880d681SAndroid Build Coastguard Worker static const uint16_t MULOpc[] =
2784*9880d681SAndroid Build Coastguard Worker { X86::MUL8r, X86::MUL16r, X86::MUL32r, X86::MUL64r };
2785*9880d681SAndroid Build Coastguard Worker static const MCPhysReg Reg[] = { X86::AL, X86::AX, X86::EAX, X86::RAX };
2786*9880d681SAndroid Build Coastguard Worker // First copy the first operand into RAX, which is an implicit input to
2787*9880d681SAndroid Build Coastguard Worker // the X86::MUL*r instruction.
2788*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2789*9880d681SAndroid Build Coastguard Worker TII.get(TargetOpcode::COPY), Reg[VT.SimpleTy-MVT::i8])
2790*9880d681SAndroid Build Coastguard Worker .addReg(LHSReg, getKillRegState(LHSIsKill));
2791*9880d681SAndroid Build Coastguard Worker ResultReg = fastEmitInst_r(MULOpc[VT.SimpleTy-MVT::i8],
2792*9880d681SAndroid Build Coastguard Worker TLI.getRegClassFor(VT), RHSReg, RHSIsKill);
2793*9880d681SAndroid Build Coastguard Worker } else if (BaseOpc == X86ISD::SMUL && !ResultReg) {
2794*9880d681SAndroid Build Coastguard Worker static const uint16_t MULOpc[] =
2795*9880d681SAndroid Build Coastguard Worker { X86::IMUL8r, X86::IMUL16rr, X86::IMUL32rr, X86::IMUL64rr };
2796*9880d681SAndroid Build Coastguard Worker if (VT == MVT::i8) {
2797*9880d681SAndroid Build Coastguard Worker // Copy the first operand into AL, which is an implicit input to the
2798*9880d681SAndroid Build Coastguard Worker // X86::IMUL8r instruction.
2799*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2800*9880d681SAndroid Build Coastguard Worker TII.get(TargetOpcode::COPY), X86::AL)
2801*9880d681SAndroid Build Coastguard Worker .addReg(LHSReg, getKillRegState(LHSIsKill));
2802*9880d681SAndroid Build Coastguard Worker ResultReg = fastEmitInst_r(MULOpc[0], TLI.getRegClassFor(VT), RHSReg,
2803*9880d681SAndroid Build Coastguard Worker RHSIsKill);
2804*9880d681SAndroid Build Coastguard Worker } else
2805*9880d681SAndroid Build Coastguard Worker ResultReg = fastEmitInst_rr(MULOpc[VT.SimpleTy-MVT::i8],
2806*9880d681SAndroid Build Coastguard Worker TLI.getRegClassFor(VT), LHSReg, LHSIsKill,
2807*9880d681SAndroid Build Coastguard Worker RHSReg, RHSIsKill);
2808*9880d681SAndroid Build Coastguard Worker }
2809*9880d681SAndroid Build Coastguard Worker
2810*9880d681SAndroid Build Coastguard Worker if (!ResultReg)
2811*9880d681SAndroid Build Coastguard Worker return false;
2812*9880d681SAndroid Build Coastguard Worker
2813*9880d681SAndroid Build Coastguard Worker unsigned ResultReg2 = FuncInfo.CreateRegs(CondTy);
2814*9880d681SAndroid Build Coastguard Worker assert((ResultReg+1) == ResultReg2 && "Nonconsecutive result registers.");
2815*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(CondOpc),
2816*9880d681SAndroid Build Coastguard Worker ResultReg2);
2817*9880d681SAndroid Build Coastguard Worker
2818*9880d681SAndroid Build Coastguard Worker updateValueMap(II, ResultReg, 2);
2819*9880d681SAndroid Build Coastguard Worker return true;
2820*9880d681SAndroid Build Coastguard Worker }
2821*9880d681SAndroid Build Coastguard Worker case Intrinsic::x86_sse_cvttss2si:
2822*9880d681SAndroid Build Coastguard Worker case Intrinsic::x86_sse_cvttss2si64:
2823*9880d681SAndroid Build Coastguard Worker case Intrinsic::x86_sse2_cvttsd2si:
2824*9880d681SAndroid Build Coastguard Worker case Intrinsic::x86_sse2_cvttsd2si64: {
2825*9880d681SAndroid Build Coastguard Worker bool IsInputDouble;
2826*9880d681SAndroid Build Coastguard Worker switch (II->getIntrinsicID()) {
2827*9880d681SAndroid Build Coastguard Worker default: llvm_unreachable("Unexpected intrinsic.");
2828*9880d681SAndroid Build Coastguard Worker case Intrinsic::x86_sse_cvttss2si:
2829*9880d681SAndroid Build Coastguard Worker case Intrinsic::x86_sse_cvttss2si64:
2830*9880d681SAndroid Build Coastguard Worker if (!Subtarget->hasSSE1())
2831*9880d681SAndroid Build Coastguard Worker return false;
2832*9880d681SAndroid Build Coastguard Worker IsInputDouble = false;
2833*9880d681SAndroid Build Coastguard Worker break;
2834*9880d681SAndroid Build Coastguard Worker case Intrinsic::x86_sse2_cvttsd2si:
2835*9880d681SAndroid Build Coastguard Worker case Intrinsic::x86_sse2_cvttsd2si64:
2836*9880d681SAndroid Build Coastguard Worker if (!Subtarget->hasSSE2())
2837*9880d681SAndroid Build Coastguard Worker return false;
2838*9880d681SAndroid Build Coastguard Worker IsInputDouble = true;
2839*9880d681SAndroid Build Coastguard Worker break;
2840*9880d681SAndroid Build Coastguard Worker }
2841*9880d681SAndroid Build Coastguard Worker
2842*9880d681SAndroid Build Coastguard Worker Type *RetTy = II->getCalledFunction()->getReturnType();
2843*9880d681SAndroid Build Coastguard Worker MVT VT;
2844*9880d681SAndroid Build Coastguard Worker if (!isTypeLegal(RetTy, VT))
2845*9880d681SAndroid Build Coastguard Worker return false;
2846*9880d681SAndroid Build Coastguard Worker
2847*9880d681SAndroid Build Coastguard Worker static const uint16_t CvtOpc[2][2][2] = {
2848*9880d681SAndroid Build Coastguard Worker { { X86::CVTTSS2SIrr, X86::VCVTTSS2SIrr },
2849*9880d681SAndroid Build Coastguard Worker { X86::CVTTSS2SI64rr, X86::VCVTTSS2SI64rr } },
2850*9880d681SAndroid Build Coastguard Worker { { X86::CVTTSD2SIrr, X86::VCVTTSD2SIrr },
2851*9880d681SAndroid Build Coastguard Worker { X86::CVTTSD2SI64rr, X86::VCVTTSD2SI64rr } }
2852*9880d681SAndroid Build Coastguard Worker };
2853*9880d681SAndroid Build Coastguard Worker bool HasAVX = Subtarget->hasAVX();
2854*9880d681SAndroid Build Coastguard Worker unsigned Opc;
2855*9880d681SAndroid Build Coastguard Worker switch (VT.SimpleTy) {
2856*9880d681SAndroid Build Coastguard Worker default: llvm_unreachable("Unexpected result type.");
2857*9880d681SAndroid Build Coastguard Worker case MVT::i32: Opc = CvtOpc[IsInputDouble][0][HasAVX]; break;
2858*9880d681SAndroid Build Coastguard Worker case MVT::i64: Opc = CvtOpc[IsInputDouble][1][HasAVX]; break;
2859*9880d681SAndroid Build Coastguard Worker }
2860*9880d681SAndroid Build Coastguard Worker
2861*9880d681SAndroid Build Coastguard Worker // Check if we can fold insertelement instructions into the convert.
2862*9880d681SAndroid Build Coastguard Worker const Value *Op = II->getArgOperand(0);
2863*9880d681SAndroid Build Coastguard Worker while (auto *IE = dyn_cast<InsertElementInst>(Op)) {
2864*9880d681SAndroid Build Coastguard Worker const Value *Index = IE->getOperand(2);
2865*9880d681SAndroid Build Coastguard Worker if (!isa<ConstantInt>(Index))
2866*9880d681SAndroid Build Coastguard Worker break;
2867*9880d681SAndroid Build Coastguard Worker unsigned Idx = cast<ConstantInt>(Index)->getZExtValue();
2868*9880d681SAndroid Build Coastguard Worker
2869*9880d681SAndroid Build Coastguard Worker if (Idx == 0) {
2870*9880d681SAndroid Build Coastguard Worker Op = IE->getOperand(1);
2871*9880d681SAndroid Build Coastguard Worker break;
2872*9880d681SAndroid Build Coastguard Worker }
2873*9880d681SAndroid Build Coastguard Worker Op = IE->getOperand(0);
2874*9880d681SAndroid Build Coastguard Worker }
2875*9880d681SAndroid Build Coastguard Worker
2876*9880d681SAndroid Build Coastguard Worker unsigned Reg = getRegForValue(Op);
2877*9880d681SAndroid Build Coastguard Worker if (Reg == 0)
2878*9880d681SAndroid Build Coastguard Worker return false;
2879*9880d681SAndroid Build Coastguard Worker
2880*9880d681SAndroid Build Coastguard Worker unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT));
2881*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
2882*9880d681SAndroid Build Coastguard Worker .addReg(Reg);
2883*9880d681SAndroid Build Coastguard Worker
2884*9880d681SAndroid Build Coastguard Worker updateValueMap(II, ResultReg);
2885*9880d681SAndroid Build Coastguard Worker return true;
2886*9880d681SAndroid Build Coastguard Worker }
2887*9880d681SAndroid Build Coastguard Worker }
2888*9880d681SAndroid Build Coastguard Worker }
2889*9880d681SAndroid Build Coastguard Worker
fastLowerArguments()2890*9880d681SAndroid Build Coastguard Worker bool X86FastISel::fastLowerArguments() {
2891*9880d681SAndroid Build Coastguard Worker if (!FuncInfo.CanLowerReturn)
2892*9880d681SAndroid Build Coastguard Worker return false;
2893*9880d681SAndroid Build Coastguard Worker
2894*9880d681SAndroid Build Coastguard Worker const Function *F = FuncInfo.Fn;
2895*9880d681SAndroid Build Coastguard Worker if (F->isVarArg())
2896*9880d681SAndroid Build Coastguard Worker return false;
2897*9880d681SAndroid Build Coastguard Worker
2898*9880d681SAndroid Build Coastguard Worker CallingConv::ID CC = F->getCallingConv();
2899*9880d681SAndroid Build Coastguard Worker if (CC != CallingConv::C)
2900*9880d681SAndroid Build Coastguard Worker return false;
2901*9880d681SAndroid Build Coastguard Worker
2902*9880d681SAndroid Build Coastguard Worker if (Subtarget->isCallingConvWin64(CC))
2903*9880d681SAndroid Build Coastguard Worker return false;
2904*9880d681SAndroid Build Coastguard Worker
2905*9880d681SAndroid Build Coastguard Worker if (!Subtarget->is64Bit())
2906*9880d681SAndroid Build Coastguard Worker return false;
2907*9880d681SAndroid Build Coastguard Worker
2908*9880d681SAndroid Build Coastguard Worker // Only handle simple cases. i.e. Up to 6 i32/i64 scalar arguments.
2909*9880d681SAndroid Build Coastguard Worker unsigned GPRCnt = 0;
2910*9880d681SAndroid Build Coastguard Worker unsigned FPRCnt = 0;
2911*9880d681SAndroid Build Coastguard Worker unsigned Idx = 0;
2912*9880d681SAndroid Build Coastguard Worker for (auto const &Arg : F->args()) {
2913*9880d681SAndroid Build Coastguard Worker // The first argument is at index 1.
2914*9880d681SAndroid Build Coastguard Worker ++Idx;
2915*9880d681SAndroid Build Coastguard Worker if (F->getAttributes().hasAttribute(Idx, Attribute::ByVal) ||
2916*9880d681SAndroid Build Coastguard Worker F->getAttributes().hasAttribute(Idx, Attribute::InReg) ||
2917*9880d681SAndroid Build Coastguard Worker F->getAttributes().hasAttribute(Idx, Attribute::StructRet) ||
2918*9880d681SAndroid Build Coastguard Worker F->getAttributes().hasAttribute(Idx, Attribute::SwiftSelf) ||
2919*9880d681SAndroid Build Coastguard Worker F->getAttributes().hasAttribute(Idx, Attribute::SwiftError) ||
2920*9880d681SAndroid Build Coastguard Worker F->getAttributes().hasAttribute(Idx, Attribute::Nest))
2921*9880d681SAndroid Build Coastguard Worker return false;
2922*9880d681SAndroid Build Coastguard Worker
2923*9880d681SAndroid Build Coastguard Worker Type *ArgTy = Arg.getType();
2924*9880d681SAndroid Build Coastguard Worker if (ArgTy->isStructTy() || ArgTy->isArrayTy() || ArgTy->isVectorTy())
2925*9880d681SAndroid Build Coastguard Worker return false;
2926*9880d681SAndroid Build Coastguard Worker
2927*9880d681SAndroid Build Coastguard Worker EVT ArgVT = TLI.getValueType(DL, ArgTy);
2928*9880d681SAndroid Build Coastguard Worker if (!ArgVT.isSimple()) return false;
2929*9880d681SAndroid Build Coastguard Worker switch (ArgVT.getSimpleVT().SimpleTy) {
2930*9880d681SAndroid Build Coastguard Worker default: return false;
2931*9880d681SAndroid Build Coastguard Worker case MVT::i32:
2932*9880d681SAndroid Build Coastguard Worker case MVT::i64:
2933*9880d681SAndroid Build Coastguard Worker ++GPRCnt;
2934*9880d681SAndroid Build Coastguard Worker break;
2935*9880d681SAndroid Build Coastguard Worker case MVT::f32:
2936*9880d681SAndroid Build Coastguard Worker case MVT::f64:
2937*9880d681SAndroid Build Coastguard Worker if (!Subtarget->hasSSE1())
2938*9880d681SAndroid Build Coastguard Worker return false;
2939*9880d681SAndroid Build Coastguard Worker ++FPRCnt;
2940*9880d681SAndroid Build Coastguard Worker break;
2941*9880d681SAndroid Build Coastguard Worker }
2942*9880d681SAndroid Build Coastguard Worker
2943*9880d681SAndroid Build Coastguard Worker if (GPRCnt > 6)
2944*9880d681SAndroid Build Coastguard Worker return false;
2945*9880d681SAndroid Build Coastguard Worker
2946*9880d681SAndroid Build Coastguard Worker if (FPRCnt > 8)
2947*9880d681SAndroid Build Coastguard Worker return false;
2948*9880d681SAndroid Build Coastguard Worker }
2949*9880d681SAndroid Build Coastguard Worker
2950*9880d681SAndroid Build Coastguard Worker static const MCPhysReg GPR32ArgRegs[] = {
2951*9880d681SAndroid Build Coastguard Worker X86::EDI, X86::ESI, X86::EDX, X86::ECX, X86::R8D, X86::R9D
2952*9880d681SAndroid Build Coastguard Worker };
2953*9880d681SAndroid Build Coastguard Worker static const MCPhysReg GPR64ArgRegs[] = {
2954*9880d681SAndroid Build Coastguard Worker X86::RDI, X86::RSI, X86::RDX, X86::RCX, X86::R8 , X86::R9
2955*9880d681SAndroid Build Coastguard Worker };
2956*9880d681SAndroid Build Coastguard Worker static const MCPhysReg XMMArgRegs[] = {
2957*9880d681SAndroid Build Coastguard Worker X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3,
2958*9880d681SAndroid Build Coastguard Worker X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7
2959*9880d681SAndroid Build Coastguard Worker };
2960*9880d681SAndroid Build Coastguard Worker
2961*9880d681SAndroid Build Coastguard Worker unsigned GPRIdx = 0;
2962*9880d681SAndroid Build Coastguard Worker unsigned FPRIdx = 0;
2963*9880d681SAndroid Build Coastguard Worker for (auto const &Arg : F->args()) {
2964*9880d681SAndroid Build Coastguard Worker MVT VT = TLI.getSimpleValueType(DL, Arg.getType());
2965*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = TLI.getRegClassFor(VT);
2966*9880d681SAndroid Build Coastguard Worker unsigned SrcReg;
2967*9880d681SAndroid Build Coastguard Worker switch (VT.SimpleTy) {
2968*9880d681SAndroid Build Coastguard Worker default: llvm_unreachable("Unexpected value type.");
2969*9880d681SAndroid Build Coastguard Worker case MVT::i32: SrcReg = GPR32ArgRegs[GPRIdx++]; break;
2970*9880d681SAndroid Build Coastguard Worker case MVT::i64: SrcReg = GPR64ArgRegs[GPRIdx++]; break;
2971*9880d681SAndroid Build Coastguard Worker case MVT::f32: // fall-through
2972*9880d681SAndroid Build Coastguard Worker case MVT::f64: SrcReg = XMMArgRegs[FPRIdx++]; break;
2973*9880d681SAndroid Build Coastguard Worker }
2974*9880d681SAndroid Build Coastguard Worker unsigned DstReg = FuncInfo.MF->addLiveIn(SrcReg, RC);
2975*9880d681SAndroid Build Coastguard Worker // FIXME: Unfortunately it's necessary to emit a copy from the livein copy.
2976*9880d681SAndroid Build Coastguard Worker // Without this, EmitLiveInCopies may eliminate the livein if its only
2977*9880d681SAndroid Build Coastguard Worker // use is a bitcast (which isn't turned into an instruction).
2978*9880d681SAndroid Build Coastguard Worker unsigned ResultReg = createResultReg(RC);
2979*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2980*9880d681SAndroid Build Coastguard Worker TII.get(TargetOpcode::COPY), ResultReg)
2981*9880d681SAndroid Build Coastguard Worker .addReg(DstReg, getKillRegState(true));
2982*9880d681SAndroid Build Coastguard Worker updateValueMap(&Arg, ResultReg);
2983*9880d681SAndroid Build Coastguard Worker }
2984*9880d681SAndroid Build Coastguard Worker return true;
2985*9880d681SAndroid Build Coastguard Worker }
2986*9880d681SAndroid Build Coastguard Worker
computeBytesPoppedByCalleeForSRet(const X86Subtarget * Subtarget,CallingConv::ID CC,ImmutableCallSite * CS)2987*9880d681SAndroid Build Coastguard Worker static unsigned computeBytesPoppedByCalleeForSRet(const X86Subtarget *Subtarget,
2988*9880d681SAndroid Build Coastguard Worker CallingConv::ID CC,
2989*9880d681SAndroid Build Coastguard Worker ImmutableCallSite *CS) {
2990*9880d681SAndroid Build Coastguard Worker if (Subtarget->is64Bit())
2991*9880d681SAndroid Build Coastguard Worker return 0;
2992*9880d681SAndroid Build Coastguard Worker if (Subtarget->getTargetTriple().isOSMSVCRT())
2993*9880d681SAndroid Build Coastguard Worker return 0;
2994*9880d681SAndroid Build Coastguard Worker if (CC == CallingConv::Fast || CC == CallingConv::GHC ||
2995*9880d681SAndroid Build Coastguard Worker CC == CallingConv::HiPE)
2996*9880d681SAndroid Build Coastguard Worker return 0;
2997*9880d681SAndroid Build Coastguard Worker
2998*9880d681SAndroid Build Coastguard Worker if (CS)
2999*9880d681SAndroid Build Coastguard Worker if (CS->arg_empty() || !CS->paramHasAttr(1, Attribute::StructRet) ||
3000*9880d681SAndroid Build Coastguard Worker CS->paramHasAttr(1, Attribute::InReg) || Subtarget->isTargetMCU())
3001*9880d681SAndroid Build Coastguard Worker return 0;
3002*9880d681SAndroid Build Coastguard Worker
3003*9880d681SAndroid Build Coastguard Worker return 4;
3004*9880d681SAndroid Build Coastguard Worker }
3005*9880d681SAndroid Build Coastguard Worker
fastLowerCall(CallLoweringInfo & CLI)3006*9880d681SAndroid Build Coastguard Worker bool X86FastISel::fastLowerCall(CallLoweringInfo &CLI) {
3007*9880d681SAndroid Build Coastguard Worker auto &OutVals = CLI.OutVals;
3008*9880d681SAndroid Build Coastguard Worker auto &OutFlags = CLI.OutFlags;
3009*9880d681SAndroid Build Coastguard Worker auto &OutRegs = CLI.OutRegs;
3010*9880d681SAndroid Build Coastguard Worker auto &Ins = CLI.Ins;
3011*9880d681SAndroid Build Coastguard Worker auto &InRegs = CLI.InRegs;
3012*9880d681SAndroid Build Coastguard Worker CallingConv::ID CC = CLI.CallConv;
3013*9880d681SAndroid Build Coastguard Worker bool &IsTailCall = CLI.IsTailCall;
3014*9880d681SAndroid Build Coastguard Worker bool IsVarArg = CLI.IsVarArg;
3015*9880d681SAndroid Build Coastguard Worker const Value *Callee = CLI.Callee;
3016*9880d681SAndroid Build Coastguard Worker MCSymbol *Symbol = CLI.Symbol;
3017*9880d681SAndroid Build Coastguard Worker
3018*9880d681SAndroid Build Coastguard Worker bool Is64Bit = Subtarget->is64Bit();
3019*9880d681SAndroid Build Coastguard Worker bool IsWin64 = Subtarget->isCallingConvWin64(CC);
3020*9880d681SAndroid Build Coastguard Worker
3021*9880d681SAndroid Build Coastguard Worker // Handle only C, fastcc, and webkit_js calling conventions for now.
3022*9880d681SAndroid Build Coastguard Worker switch (CC) {
3023*9880d681SAndroid Build Coastguard Worker default: return false;
3024*9880d681SAndroid Build Coastguard Worker case CallingConv::C:
3025*9880d681SAndroid Build Coastguard Worker case CallingConv::Fast:
3026*9880d681SAndroid Build Coastguard Worker case CallingConv::WebKit_JS:
3027*9880d681SAndroid Build Coastguard Worker case CallingConv::Swift:
3028*9880d681SAndroid Build Coastguard Worker case CallingConv::X86_FastCall:
3029*9880d681SAndroid Build Coastguard Worker case CallingConv::X86_StdCall:
3030*9880d681SAndroid Build Coastguard Worker case CallingConv::X86_ThisCall:
3031*9880d681SAndroid Build Coastguard Worker case CallingConv::X86_64_Win64:
3032*9880d681SAndroid Build Coastguard Worker case CallingConv::X86_64_SysV:
3033*9880d681SAndroid Build Coastguard Worker break;
3034*9880d681SAndroid Build Coastguard Worker }
3035*9880d681SAndroid Build Coastguard Worker
3036*9880d681SAndroid Build Coastguard Worker // Allow SelectionDAG isel to handle tail calls.
3037*9880d681SAndroid Build Coastguard Worker if (IsTailCall)
3038*9880d681SAndroid Build Coastguard Worker return false;
3039*9880d681SAndroid Build Coastguard Worker
3040*9880d681SAndroid Build Coastguard Worker // fastcc with -tailcallopt is intended to provide a guaranteed
3041*9880d681SAndroid Build Coastguard Worker // tail call optimization. Fastisel doesn't know how to do that.
3042*9880d681SAndroid Build Coastguard Worker if (CC == CallingConv::Fast && TM.Options.GuaranteedTailCallOpt)
3043*9880d681SAndroid Build Coastguard Worker return false;
3044*9880d681SAndroid Build Coastguard Worker
3045*9880d681SAndroid Build Coastguard Worker // Don't know how to handle Win64 varargs yet. Nothing special needed for
3046*9880d681SAndroid Build Coastguard Worker // x86-32. Special handling for x86-64 is implemented.
3047*9880d681SAndroid Build Coastguard Worker if (IsVarArg && IsWin64)
3048*9880d681SAndroid Build Coastguard Worker return false;
3049*9880d681SAndroid Build Coastguard Worker
3050*9880d681SAndroid Build Coastguard Worker // Don't know about inalloca yet.
3051*9880d681SAndroid Build Coastguard Worker if (CLI.CS && CLI.CS->hasInAllocaArgument())
3052*9880d681SAndroid Build Coastguard Worker return false;
3053*9880d681SAndroid Build Coastguard Worker
3054*9880d681SAndroid Build Coastguard Worker for (auto Flag : CLI.OutFlags)
3055*9880d681SAndroid Build Coastguard Worker if (Flag.isSwiftError())
3056*9880d681SAndroid Build Coastguard Worker return false;
3057*9880d681SAndroid Build Coastguard Worker
3058*9880d681SAndroid Build Coastguard Worker SmallVector<MVT, 16> OutVTs;
3059*9880d681SAndroid Build Coastguard Worker SmallVector<unsigned, 16> ArgRegs;
3060*9880d681SAndroid Build Coastguard Worker
3061*9880d681SAndroid Build Coastguard Worker // If this is a constant i1/i8/i16 argument, promote to i32 to avoid an extra
3062*9880d681SAndroid Build Coastguard Worker // instruction. This is safe because it is common to all FastISel supported
3063*9880d681SAndroid Build Coastguard Worker // calling conventions on x86.
3064*9880d681SAndroid Build Coastguard Worker for (int i = 0, e = OutVals.size(); i != e; ++i) {
3065*9880d681SAndroid Build Coastguard Worker Value *&Val = OutVals[i];
3066*9880d681SAndroid Build Coastguard Worker ISD::ArgFlagsTy Flags = OutFlags[i];
3067*9880d681SAndroid Build Coastguard Worker if (auto *CI = dyn_cast<ConstantInt>(Val)) {
3068*9880d681SAndroid Build Coastguard Worker if (CI->getBitWidth() < 32) {
3069*9880d681SAndroid Build Coastguard Worker if (Flags.isSExt())
3070*9880d681SAndroid Build Coastguard Worker Val = ConstantExpr::getSExt(CI, Type::getInt32Ty(CI->getContext()));
3071*9880d681SAndroid Build Coastguard Worker else
3072*9880d681SAndroid Build Coastguard Worker Val = ConstantExpr::getZExt(CI, Type::getInt32Ty(CI->getContext()));
3073*9880d681SAndroid Build Coastguard Worker }
3074*9880d681SAndroid Build Coastguard Worker }
3075*9880d681SAndroid Build Coastguard Worker
3076*9880d681SAndroid Build Coastguard Worker // Passing bools around ends up doing a trunc to i1 and passing it.
3077*9880d681SAndroid Build Coastguard Worker // Codegen this as an argument + "and 1".
3078*9880d681SAndroid Build Coastguard Worker MVT VT;
3079*9880d681SAndroid Build Coastguard Worker auto *TI = dyn_cast<TruncInst>(Val);
3080*9880d681SAndroid Build Coastguard Worker unsigned ResultReg;
3081*9880d681SAndroid Build Coastguard Worker if (TI && TI->getType()->isIntegerTy(1) && CLI.CS &&
3082*9880d681SAndroid Build Coastguard Worker (TI->getParent() == CLI.CS->getInstruction()->getParent()) &&
3083*9880d681SAndroid Build Coastguard Worker TI->hasOneUse()) {
3084*9880d681SAndroid Build Coastguard Worker Value *PrevVal = TI->getOperand(0);
3085*9880d681SAndroid Build Coastguard Worker ResultReg = getRegForValue(PrevVal);
3086*9880d681SAndroid Build Coastguard Worker
3087*9880d681SAndroid Build Coastguard Worker if (!ResultReg)
3088*9880d681SAndroid Build Coastguard Worker return false;
3089*9880d681SAndroid Build Coastguard Worker
3090*9880d681SAndroid Build Coastguard Worker if (!isTypeLegal(PrevVal->getType(), VT))
3091*9880d681SAndroid Build Coastguard Worker return false;
3092*9880d681SAndroid Build Coastguard Worker
3093*9880d681SAndroid Build Coastguard Worker ResultReg =
3094*9880d681SAndroid Build Coastguard Worker fastEmit_ri(VT, VT, ISD::AND, ResultReg, hasTrivialKill(PrevVal), 1);
3095*9880d681SAndroid Build Coastguard Worker } else {
3096*9880d681SAndroid Build Coastguard Worker if (!isTypeLegal(Val->getType(), VT))
3097*9880d681SAndroid Build Coastguard Worker return false;
3098*9880d681SAndroid Build Coastguard Worker ResultReg = getRegForValue(Val);
3099*9880d681SAndroid Build Coastguard Worker }
3100*9880d681SAndroid Build Coastguard Worker
3101*9880d681SAndroid Build Coastguard Worker if (!ResultReg)
3102*9880d681SAndroid Build Coastguard Worker return false;
3103*9880d681SAndroid Build Coastguard Worker
3104*9880d681SAndroid Build Coastguard Worker ArgRegs.push_back(ResultReg);
3105*9880d681SAndroid Build Coastguard Worker OutVTs.push_back(VT);
3106*9880d681SAndroid Build Coastguard Worker }
3107*9880d681SAndroid Build Coastguard Worker
3108*9880d681SAndroid Build Coastguard Worker // Analyze operands of the call, assigning locations to each operand.
3109*9880d681SAndroid Build Coastguard Worker SmallVector<CCValAssign, 16> ArgLocs;
3110*9880d681SAndroid Build Coastguard Worker CCState CCInfo(CC, IsVarArg, *FuncInfo.MF, ArgLocs, CLI.RetTy->getContext());
3111*9880d681SAndroid Build Coastguard Worker
3112*9880d681SAndroid Build Coastguard Worker // Allocate shadow area for Win64
3113*9880d681SAndroid Build Coastguard Worker if (IsWin64)
3114*9880d681SAndroid Build Coastguard Worker CCInfo.AllocateStack(32, 8);
3115*9880d681SAndroid Build Coastguard Worker
3116*9880d681SAndroid Build Coastguard Worker CCInfo.AnalyzeCallOperands(OutVTs, OutFlags, CC_X86);
3117*9880d681SAndroid Build Coastguard Worker
3118*9880d681SAndroid Build Coastguard Worker // Get a count of how many bytes are to be pushed on the stack.
3119*9880d681SAndroid Build Coastguard Worker unsigned NumBytes = CCInfo.getAlignedCallFrameSize();
3120*9880d681SAndroid Build Coastguard Worker
3121*9880d681SAndroid Build Coastguard Worker // Issue CALLSEQ_START
3122*9880d681SAndroid Build Coastguard Worker unsigned AdjStackDown = TII.getCallFrameSetupOpcode();
3123*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AdjStackDown))
3124*9880d681SAndroid Build Coastguard Worker .addImm(NumBytes).addImm(0);
3125*9880d681SAndroid Build Coastguard Worker
3126*9880d681SAndroid Build Coastguard Worker // Walk the register/memloc assignments, inserting copies/loads.
3127*9880d681SAndroid Build Coastguard Worker const X86RegisterInfo *RegInfo = Subtarget->getRegisterInfo();
3128*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
3129*9880d681SAndroid Build Coastguard Worker CCValAssign const &VA = ArgLocs[i];
3130*9880d681SAndroid Build Coastguard Worker const Value *ArgVal = OutVals[VA.getValNo()];
3131*9880d681SAndroid Build Coastguard Worker MVT ArgVT = OutVTs[VA.getValNo()];
3132*9880d681SAndroid Build Coastguard Worker
3133*9880d681SAndroid Build Coastguard Worker if (ArgVT == MVT::x86mmx)
3134*9880d681SAndroid Build Coastguard Worker return false;
3135*9880d681SAndroid Build Coastguard Worker
3136*9880d681SAndroid Build Coastguard Worker unsigned ArgReg = ArgRegs[VA.getValNo()];
3137*9880d681SAndroid Build Coastguard Worker
3138*9880d681SAndroid Build Coastguard Worker // Promote the value if needed.
3139*9880d681SAndroid Build Coastguard Worker switch (VA.getLocInfo()) {
3140*9880d681SAndroid Build Coastguard Worker case CCValAssign::Full: break;
3141*9880d681SAndroid Build Coastguard Worker case CCValAssign::SExt: {
3142*9880d681SAndroid Build Coastguard Worker assert(VA.getLocVT().isInteger() && !VA.getLocVT().isVector() &&
3143*9880d681SAndroid Build Coastguard Worker "Unexpected extend");
3144*9880d681SAndroid Build Coastguard Worker
3145*9880d681SAndroid Build Coastguard Worker if (ArgVT.SimpleTy == MVT::i1)
3146*9880d681SAndroid Build Coastguard Worker return false;
3147*9880d681SAndroid Build Coastguard Worker
3148*9880d681SAndroid Build Coastguard Worker bool Emitted = X86FastEmitExtend(ISD::SIGN_EXTEND, VA.getLocVT(), ArgReg,
3149*9880d681SAndroid Build Coastguard Worker ArgVT, ArgReg);
3150*9880d681SAndroid Build Coastguard Worker assert(Emitted && "Failed to emit a sext!"); (void)Emitted;
3151*9880d681SAndroid Build Coastguard Worker ArgVT = VA.getLocVT();
3152*9880d681SAndroid Build Coastguard Worker break;
3153*9880d681SAndroid Build Coastguard Worker }
3154*9880d681SAndroid Build Coastguard Worker case CCValAssign::ZExt: {
3155*9880d681SAndroid Build Coastguard Worker assert(VA.getLocVT().isInteger() && !VA.getLocVT().isVector() &&
3156*9880d681SAndroid Build Coastguard Worker "Unexpected extend");
3157*9880d681SAndroid Build Coastguard Worker
3158*9880d681SAndroid Build Coastguard Worker // Handle zero-extension from i1 to i8, which is common.
3159*9880d681SAndroid Build Coastguard Worker if (ArgVT.SimpleTy == MVT::i1) {
3160*9880d681SAndroid Build Coastguard Worker // Set the high bits to zero.
3161*9880d681SAndroid Build Coastguard Worker ArgReg = fastEmitZExtFromI1(MVT::i8, ArgReg, /*TODO: Kill=*/false);
3162*9880d681SAndroid Build Coastguard Worker ArgVT = MVT::i8;
3163*9880d681SAndroid Build Coastguard Worker
3164*9880d681SAndroid Build Coastguard Worker if (ArgReg == 0)
3165*9880d681SAndroid Build Coastguard Worker return false;
3166*9880d681SAndroid Build Coastguard Worker }
3167*9880d681SAndroid Build Coastguard Worker
3168*9880d681SAndroid Build Coastguard Worker bool Emitted = X86FastEmitExtend(ISD::ZERO_EXTEND, VA.getLocVT(), ArgReg,
3169*9880d681SAndroid Build Coastguard Worker ArgVT, ArgReg);
3170*9880d681SAndroid Build Coastguard Worker assert(Emitted && "Failed to emit a zext!"); (void)Emitted;
3171*9880d681SAndroid Build Coastguard Worker ArgVT = VA.getLocVT();
3172*9880d681SAndroid Build Coastguard Worker break;
3173*9880d681SAndroid Build Coastguard Worker }
3174*9880d681SAndroid Build Coastguard Worker case CCValAssign::AExt: {
3175*9880d681SAndroid Build Coastguard Worker assert(VA.getLocVT().isInteger() && !VA.getLocVT().isVector() &&
3176*9880d681SAndroid Build Coastguard Worker "Unexpected extend");
3177*9880d681SAndroid Build Coastguard Worker bool Emitted = X86FastEmitExtend(ISD::ANY_EXTEND, VA.getLocVT(), ArgReg,
3178*9880d681SAndroid Build Coastguard Worker ArgVT, ArgReg);
3179*9880d681SAndroid Build Coastguard Worker if (!Emitted)
3180*9880d681SAndroid Build Coastguard Worker Emitted = X86FastEmitExtend(ISD::ZERO_EXTEND, VA.getLocVT(), ArgReg,
3181*9880d681SAndroid Build Coastguard Worker ArgVT, ArgReg);
3182*9880d681SAndroid Build Coastguard Worker if (!Emitted)
3183*9880d681SAndroid Build Coastguard Worker Emitted = X86FastEmitExtend(ISD::SIGN_EXTEND, VA.getLocVT(), ArgReg,
3184*9880d681SAndroid Build Coastguard Worker ArgVT, ArgReg);
3185*9880d681SAndroid Build Coastguard Worker
3186*9880d681SAndroid Build Coastguard Worker assert(Emitted && "Failed to emit a aext!"); (void)Emitted;
3187*9880d681SAndroid Build Coastguard Worker ArgVT = VA.getLocVT();
3188*9880d681SAndroid Build Coastguard Worker break;
3189*9880d681SAndroid Build Coastguard Worker }
3190*9880d681SAndroid Build Coastguard Worker case CCValAssign::BCvt: {
3191*9880d681SAndroid Build Coastguard Worker ArgReg = fastEmit_r(ArgVT, VA.getLocVT(), ISD::BITCAST, ArgReg,
3192*9880d681SAndroid Build Coastguard Worker /*TODO: Kill=*/false);
3193*9880d681SAndroid Build Coastguard Worker assert(ArgReg && "Failed to emit a bitcast!");
3194*9880d681SAndroid Build Coastguard Worker ArgVT = VA.getLocVT();
3195*9880d681SAndroid Build Coastguard Worker break;
3196*9880d681SAndroid Build Coastguard Worker }
3197*9880d681SAndroid Build Coastguard Worker case CCValAssign::VExt:
3198*9880d681SAndroid Build Coastguard Worker // VExt has not been implemented, so this should be impossible to reach
3199*9880d681SAndroid Build Coastguard Worker // for now. However, fallback to Selection DAG isel once implemented.
3200*9880d681SAndroid Build Coastguard Worker return false;
3201*9880d681SAndroid Build Coastguard Worker case CCValAssign::AExtUpper:
3202*9880d681SAndroid Build Coastguard Worker case CCValAssign::SExtUpper:
3203*9880d681SAndroid Build Coastguard Worker case CCValAssign::ZExtUpper:
3204*9880d681SAndroid Build Coastguard Worker case CCValAssign::FPExt:
3205*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unexpected loc info!");
3206*9880d681SAndroid Build Coastguard Worker case CCValAssign::Indirect:
3207*9880d681SAndroid Build Coastguard Worker // FIXME: Indirect doesn't need extending, but fast-isel doesn't fully
3208*9880d681SAndroid Build Coastguard Worker // support this.
3209*9880d681SAndroid Build Coastguard Worker return false;
3210*9880d681SAndroid Build Coastguard Worker }
3211*9880d681SAndroid Build Coastguard Worker
3212*9880d681SAndroid Build Coastguard Worker if (VA.isRegLoc()) {
3213*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
3214*9880d681SAndroid Build Coastguard Worker TII.get(TargetOpcode::COPY), VA.getLocReg()).addReg(ArgReg);
3215*9880d681SAndroid Build Coastguard Worker OutRegs.push_back(VA.getLocReg());
3216*9880d681SAndroid Build Coastguard Worker } else {
3217*9880d681SAndroid Build Coastguard Worker assert(VA.isMemLoc());
3218*9880d681SAndroid Build Coastguard Worker
3219*9880d681SAndroid Build Coastguard Worker // Don't emit stores for undef values.
3220*9880d681SAndroid Build Coastguard Worker if (isa<UndefValue>(ArgVal))
3221*9880d681SAndroid Build Coastguard Worker continue;
3222*9880d681SAndroid Build Coastguard Worker
3223*9880d681SAndroid Build Coastguard Worker unsigned LocMemOffset = VA.getLocMemOffset();
3224*9880d681SAndroid Build Coastguard Worker X86AddressMode AM;
3225*9880d681SAndroid Build Coastguard Worker AM.Base.Reg = RegInfo->getStackRegister();
3226*9880d681SAndroid Build Coastguard Worker AM.Disp = LocMemOffset;
3227*9880d681SAndroid Build Coastguard Worker ISD::ArgFlagsTy Flags = OutFlags[VA.getValNo()];
3228*9880d681SAndroid Build Coastguard Worker unsigned Alignment = DL.getABITypeAlignment(ArgVal->getType());
3229*9880d681SAndroid Build Coastguard Worker MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
3230*9880d681SAndroid Build Coastguard Worker MachinePointerInfo::getStack(*FuncInfo.MF, LocMemOffset),
3231*9880d681SAndroid Build Coastguard Worker MachineMemOperand::MOStore, ArgVT.getStoreSize(), Alignment);
3232*9880d681SAndroid Build Coastguard Worker if (Flags.isByVal()) {
3233*9880d681SAndroid Build Coastguard Worker X86AddressMode SrcAM;
3234*9880d681SAndroid Build Coastguard Worker SrcAM.Base.Reg = ArgReg;
3235*9880d681SAndroid Build Coastguard Worker if (!TryEmitSmallMemcpy(AM, SrcAM, Flags.getByValSize()))
3236*9880d681SAndroid Build Coastguard Worker return false;
3237*9880d681SAndroid Build Coastguard Worker } else if (isa<ConstantInt>(ArgVal) || isa<ConstantPointerNull>(ArgVal)) {
3238*9880d681SAndroid Build Coastguard Worker // If this is a really simple value, emit this with the Value* version
3239*9880d681SAndroid Build Coastguard Worker // of X86FastEmitStore. If it isn't simple, we don't want to do this,
3240*9880d681SAndroid Build Coastguard Worker // as it can cause us to reevaluate the argument.
3241*9880d681SAndroid Build Coastguard Worker if (!X86FastEmitStore(ArgVT, ArgVal, AM, MMO))
3242*9880d681SAndroid Build Coastguard Worker return false;
3243*9880d681SAndroid Build Coastguard Worker } else {
3244*9880d681SAndroid Build Coastguard Worker bool ValIsKill = hasTrivialKill(ArgVal);
3245*9880d681SAndroid Build Coastguard Worker if (!X86FastEmitStore(ArgVT, ArgReg, ValIsKill, AM, MMO))
3246*9880d681SAndroid Build Coastguard Worker return false;
3247*9880d681SAndroid Build Coastguard Worker }
3248*9880d681SAndroid Build Coastguard Worker }
3249*9880d681SAndroid Build Coastguard Worker }
3250*9880d681SAndroid Build Coastguard Worker
3251*9880d681SAndroid Build Coastguard Worker // ELF / PIC requires GOT in the EBX register before function calls via PLT
3252*9880d681SAndroid Build Coastguard Worker // GOT pointer.
3253*9880d681SAndroid Build Coastguard Worker if (Subtarget->isPICStyleGOT()) {
3254*9880d681SAndroid Build Coastguard Worker unsigned Base = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
3255*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
3256*9880d681SAndroid Build Coastguard Worker TII.get(TargetOpcode::COPY), X86::EBX).addReg(Base);
3257*9880d681SAndroid Build Coastguard Worker }
3258*9880d681SAndroid Build Coastguard Worker
3259*9880d681SAndroid Build Coastguard Worker if (Is64Bit && IsVarArg && !IsWin64) {
3260*9880d681SAndroid Build Coastguard Worker // From AMD64 ABI document:
3261*9880d681SAndroid Build Coastguard Worker // For calls that may call functions that use varargs or stdargs
3262*9880d681SAndroid Build Coastguard Worker // (prototype-less calls or calls to functions containing ellipsis (...) in
3263*9880d681SAndroid Build Coastguard Worker // the declaration) %al is used as hidden argument to specify the number
3264*9880d681SAndroid Build Coastguard Worker // of SSE registers used. The contents of %al do not need to match exactly
3265*9880d681SAndroid Build Coastguard Worker // the number of registers, but must be an ubound on the number of SSE
3266*9880d681SAndroid Build Coastguard Worker // registers used and is in the range 0 - 8 inclusive.
3267*9880d681SAndroid Build Coastguard Worker
3268*9880d681SAndroid Build Coastguard Worker // Count the number of XMM registers allocated.
3269*9880d681SAndroid Build Coastguard Worker static const MCPhysReg XMMArgRegs[] = {
3270*9880d681SAndroid Build Coastguard Worker X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3,
3271*9880d681SAndroid Build Coastguard Worker X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7
3272*9880d681SAndroid Build Coastguard Worker };
3273*9880d681SAndroid Build Coastguard Worker unsigned NumXMMRegs = CCInfo.getFirstUnallocated(XMMArgRegs);
3274*9880d681SAndroid Build Coastguard Worker assert((Subtarget->hasSSE1() || !NumXMMRegs)
3275*9880d681SAndroid Build Coastguard Worker && "SSE registers cannot be used when SSE is disabled");
3276*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::MOV8ri),
3277*9880d681SAndroid Build Coastguard Worker X86::AL).addImm(NumXMMRegs);
3278*9880d681SAndroid Build Coastguard Worker }
3279*9880d681SAndroid Build Coastguard Worker
3280*9880d681SAndroid Build Coastguard Worker // Materialize callee address in a register. FIXME: GV address can be
3281*9880d681SAndroid Build Coastguard Worker // handled with a CALLpcrel32 instead.
3282*9880d681SAndroid Build Coastguard Worker X86AddressMode CalleeAM;
3283*9880d681SAndroid Build Coastguard Worker if (!X86SelectCallAddress(Callee, CalleeAM))
3284*9880d681SAndroid Build Coastguard Worker return false;
3285*9880d681SAndroid Build Coastguard Worker
3286*9880d681SAndroid Build Coastguard Worker unsigned CalleeOp = 0;
3287*9880d681SAndroid Build Coastguard Worker const GlobalValue *GV = nullptr;
3288*9880d681SAndroid Build Coastguard Worker if (CalleeAM.GV != nullptr) {
3289*9880d681SAndroid Build Coastguard Worker GV = CalleeAM.GV;
3290*9880d681SAndroid Build Coastguard Worker } else if (CalleeAM.Base.Reg != 0) {
3291*9880d681SAndroid Build Coastguard Worker CalleeOp = CalleeAM.Base.Reg;
3292*9880d681SAndroid Build Coastguard Worker } else
3293*9880d681SAndroid Build Coastguard Worker return false;
3294*9880d681SAndroid Build Coastguard Worker
3295*9880d681SAndroid Build Coastguard Worker // Issue the call.
3296*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder MIB;
3297*9880d681SAndroid Build Coastguard Worker if (CalleeOp) {
3298*9880d681SAndroid Build Coastguard Worker // Register-indirect call.
3299*9880d681SAndroid Build Coastguard Worker unsigned CallOpc = Is64Bit ? X86::CALL64r : X86::CALL32r;
3300*9880d681SAndroid Build Coastguard Worker MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(CallOpc))
3301*9880d681SAndroid Build Coastguard Worker .addReg(CalleeOp);
3302*9880d681SAndroid Build Coastguard Worker } else {
3303*9880d681SAndroid Build Coastguard Worker // Direct call.
3304*9880d681SAndroid Build Coastguard Worker assert(GV && "Not a direct call");
3305*9880d681SAndroid Build Coastguard Worker unsigned CallOpc = Is64Bit ? X86::CALL64pcrel32 : X86::CALLpcrel32;
3306*9880d681SAndroid Build Coastguard Worker
3307*9880d681SAndroid Build Coastguard Worker // See if we need any target-specific flags on the GV operand.
3308*9880d681SAndroid Build Coastguard Worker unsigned char OpFlags = Subtarget->classifyGlobalFunctionReference(GV);
3309*9880d681SAndroid Build Coastguard Worker // Ignore NonLazyBind attribute in FastISel
3310*9880d681SAndroid Build Coastguard Worker if (OpFlags == X86II::MO_GOTPCREL)
3311*9880d681SAndroid Build Coastguard Worker OpFlags = 0;
3312*9880d681SAndroid Build Coastguard Worker
3313*9880d681SAndroid Build Coastguard Worker MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(CallOpc));
3314*9880d681SAndroid Build Coastguard Worker if (Symbol)
3315*9880d681SAndroid Build Coastguard Worker MIB.addSym(Symbol, OpFlags);
3316*9880d681SAndroid Build Coastguard Worker else
3317*9880d681SAndroid Build Coastguard Worker MIB.addGlobalAddress(GV, 0, OpFlags);
3318*9880d681SAndroid Build Coastguard Worker }
3319*9880d681SAndroid Build Coastguard Worker
3320*9880d681SAndroid Build Coastguard Worker // Add a register mask operand representing the call-preserved registers.
3321*9880d681SAndroid Build Coastguard Worker // Proper defs for return values will be added by setPhysRegsDeadExcept().
3322*9880d681SAndroid Build Coastguard Worker MIB.addRegMask(TRI.getCallPreservedMask(*FuncInfo.MF, CC));
3323*9880d681SAndroid Build Coastguard Worker
3324*9880d681SAndroid Build Coastguard Worker // Add an implicit use GOT pointer in EBX.
3325*9880d681SAndroid Build Coastguard Worker if (Subtarget->isPICStyleGOT())
3326*9880d681SAndroid Build Coastguard Worker MIB.addReg(X86::EBX, RegState::Implicit);
3327*9880d681SAndroid Build Coastguard Worker
3328*9880d681SAndroid Build Coastguard Worker if (Is64Bit && IsVarArg && !IsWin64)
3329*9880d681SAndroid Build Coastguard Worker MIB.addReg(X86::AL, RegState::Implicit);
3330*9880d681SAndroid Build Coastguard Worker
3331*9880d681SAndroid Build Coastguard Worker // Add implicit physical register uses to the call.
3332*9880d681SAndroid Build Coastguard Worker for (auto Reg : OutRegs)
3333*9880d681SAndroid Build Coastguard Worker MIB.addReg(Reg, RegState::Implicit);
3334*9880d681SAndroid Build Coastguard Worker
3335*9880d681SAndroid Build Coastguard Worker // Issue CALLSEQ_END
3336*9880d681SAndroid Build Coastguard Worker unsigned NumBytesForCalleeToPop =
3337*9880d681SAndroid Build Coastguard Worker X86::isCalleePop(CC, Subtarget->is64Bit(), IsVarArg,
3338*9880d681SAndroid Build Coastguard Worker TM.Options.GuaranteedTailCallOpt)
3339*9880d681SAndroid Build Coastguard Worker ? NumBytes // Callee pops everything.
3340*9880d681SAndroid Build Coastguard Worker : computeBytesPoppedByCalleeForSRet(Subtarget, CC, CLI.CS);
3341*9880d681SAndroid Build Coastguard Worker unsigned AdjStackUp = TII.getCallFrameDestroyOpcode();
3342*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AdjStackUp))
3343*9880d681SAndroid Build Coastguard Worker .addImm(NumBytes).addImm(NumBytesForCalleeToPop);
3344*9880d681SAndroid Build Coastguard Worker
3345*9880d681SAndroid Build Coastguard Worker // Now handle call return values.
3346*9880d681SAndroid Build Coastguard Worker SmallVector<CCValAssign, 16> RVLocs;
3347*9880d681SAndroid Build Coastguard Worker CCState CCRetInfo(CC, IsVarArg, *FuncInfo.MF, RVLocs,
3348*9880d681SAndroid Build Coastguard Worker CLI.RetTy->getContext());
3349*9880d681SAndroid Build Coastguard Worker CCRetInfo.AnalyzeCallResult(Ins, RetCC_X86);
3350*9880d681SAndroid Build Coastguard Worker
3351*9880d681SAndroid Build Coastguard Worker // Copy all of the result registers out of their specified physreg.
3352*9880d681SAndroid Build Coastguard Worker unsigned ResultReg = FuncInfo.CreateRegs(CLI.RetTy);
3353*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i != RVLocs.size(); ++i) {
3354*9880d681SAndroid Build Coastguard Worker CCValAssign &VA = RVLocs[i];
3355*9880d681SAndroid Build Coastguard Worker EVT CopyVT = VA.getValVT();
3356*9880d681SAndroid Build Coastguard Worker unsigned CopyReg = ResultReg + i;
3357*9880d681SAndroid Build Coastguard Worker
3358*9880d681SAndroid Build Coastguard Worker // If this is x86-64, and we disabled SSE, we can't return FP values
3359*9880d681SAndroid Build Coastguard Worker if ((CopyVT == MVT::f32 || CopyVT == MVT::f64) &&
3360*9880d681SAndroid Build Coastguard Worker ((Is64Bit || Ins[i].Flags.isInReg()) && !Subtarget->hasSSE1())) {
3361*9880d681SAndroid Build Coastguard Worker report_fatal_error("SSE register return with SSE disabled");
3362*9880d681SAndroid Build Coastguard Worker }
3363*9880d681SAndroid Build Coastguard Worker
3364*9880d681SAndroid Build Coastguard Worker // If we prefer to use the value in xmm registers, copy it out as f80 and
3365*9880d681SAndroid Build Coastguard Worker // use a truncate to move it from fp stack reg to xmm reg.
3366*9880d681SAndroid Build Coastguard Worker if ((VA.getLocReg() == X86::FP0 || VA.getLocReg() == X86::FP1) &&
3367*9880d681SAndroid Build Coastguard Worker isScalarFPTypeInSSEReg(VA.getValVT())) {
3368*9880d681SAndroid Build Coastguard Worker CopyVT = MVT::f80;
3369*9880d681SAndroid Build Coastguard Worker CopyReg = createResultReg(&X86::RFP80RegClass);
3370*9880d681SAndroid Build Coastguard Worker }
3371*9880d681SAndroid Build Coastguard Worker
3372*9880d681SAndroid Build Coastguard Worker // Copy out the result.
3373*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
3374*9880d681SAndroid Build Coastguard Worker TII.get(TargetOpcode::COPY), CopyReg).addReg(VA.getLocReg());
3375*9880d681SAndroid Build Coastguard Worker InRegs.push_back(VA.getLocReg());
3376*9880d681SAndroid Build Coastguard Worker
3377*9880d681SAndroid Build Coastguard Worker // Round the f80 to the right size, which also moves it to the appropriate
3378*9880d681SAndroid Build Coastguard Worker // xmm register. This is accomplished by storing the f80 value in memory
3379*9880d681SAndroid Build Coastguard Worker // and then loading it back.
3380*9880d681SAndroid Build Coastguard Worker if (CopyVT != VA.getValVT()) {
3381*9880d681SAndroid Build Coastguard Worker EVT ResVT = VA.getValVT();
3382*9880d681SAndroid Build Coastguard Worker unsigned Opc = ResVT == MVT::f32 ? X86::ST_Fp80m32 : X86::ST_Fp80m64;
3383*9880d681SAndroid Build Coastguard Worker unsigned MemSize = ResVT.getSizeInBits()/8;
3384*9880d681SAndroid Build Coastguard Worker int FI = MFI.CreateStackObject(MemSize, MemSize, false);
3385*9880d681SAndroid Build Coastguard Worker addFrameReference(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
3386*9880d681SAndroid Build Coastguard Worker TII.get(Opc)), FI)
3387*9880d681SAndroid Build Coastguard Worker .addReg(CopyReg);
3388*9880d681SAndroid Build Coastguard Worker Opc = ResVT == MVT::f32 ? X86::MOVSSrm : X86::MOVSDrm;
3389*9880d681SAndroid Build Coastguard Worker addFrameReference(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
3390*9880d681SAndroid Build Coastguard Worker TII.get(Opc), ResultReg + i), FI);
3391*9880d681SAndroid Build Coastguard Worker }
3392*9880d681SAndroid Build Coastguard Worker }
3393*9880d681SAndroid Build Coastguard Worker
3394*9880d681SAndroid Build Coastguard Worker CLI.ResultReg = ResultReg;
3395*9880d681SAndroid Build Coastguard Worker CLI.NumResultRegs = RVLocs.size();
3396*9880d681SAndroid Build Coastguard Worker CLI.Call = MIB;
3397*9880d681SAndroid Build Coastguard Worker
3398*9880d681SAndroid Build Coastguard Worker return true;
3399*9880d681SAndroid Build Coastguard Worker }
3400*9880d681SAndroid Build Coastguard Worker
3401*9880d681SAndroid Build Coastguard Worker bool
fastSelectInstruction(const Instruction * I)3402*9880d681SAndroid Build Coastguard Worker X86FastISel::fastSelectInstruction(const Instruction *I) {
3403*9880d681SAndroid Build Coastguard Worker switch (I->getOpcode()) {
3404*9880d681SAndroid Build Coastguard Worker default: break;
3405*9880d681SAndroid Build Coastguard Worker case Instruction::Load:
3406*9880d681SAndroid Build Coastguard Worker return X86SelectLoad(I);
3407*9880d681SAndroid Build Coastguard Worker case Instruction::Store:
3408*9880d681SAndroid Build Coastguard Worker return X86SelectStore(I);
3409*9880d681SAndroid Build Coastguard Worker case Instruction::Ret:
3410*9880d681SAndroid Build Coastguard Worker return X86SelectRet(I);
3411*9880d681SAndroid Build Coastguard Worker case Instruction::ICmp:
3412*9880d681SAndroid Build Coastguard Worker case Instruction::FCmp:
3413*9880d681SAndroid Build Coastguard Worker return X86SelectCmp(I);
3414*9880d681SAndroid Build Coastguard Worker case Instruction::ZExt:
3415*9880d681SAndroid Build Coastguard Worker return X86SelectZExt(I);
3416*9880d681SAndroid Build Coastguard Worker case Instruction::Br:
3417*9880d681SAndroid Build Coastguard Worker return X86SelectBranch(I);
3418*9880d681SAndroid Build Coastguard Worker case Instruction::LShr:
3419*9880d681SAndroid Build Coastguard Worker case Instruction::AShr:
3420*9880d681SAndroid Build Coastguard Worker case Instruction::Shl:
3421*9880d681SAndroid Build Coastguard Worker return X86SelectShift(I);
3422*9880d681SAndroid Build Coastguard Worker case Instruction::SDiv:
3423*9880d681SAndroid Build Coastguard Worker case Instruction::UDiv:
3424*9880d681SAndroid Build Coastguard Worker case Instruction::SRem:
3425*9880d681SAndroid Build Coastguard Worker case Instruction::URem:
3426*9880d681SAndroid Build Coastguard Worker return X86SelectDivRem(I);
3427*9880d681SAndroid Build Coastguard Worker case Instruction::Select:
3428*9880d681SAndroid Build Coastguard Worker return X86SelectSelect(I);
3429*9880d681SAndroid Build Coastguard Worker case Instruction::Trunc:
3430*9880d681SAndroid Build Coastguard Worker return X86SelectTrunc(I);
3431*9880d681SAndroid Build Coastguard Worker case Instruction::FPExt:
3432*9880d681SAndroid Build Coastguard Worker return X86SelectFPExt(I);
3433*9880d681SAndroid Build Coastguard Worker case Instruction::FPTrunc:
3434*9880d681SAndroid Build Coastguard Worker return X86SelectFPTrunc(I);
3435*9880d681SAndroid Build Coastguard Worker case Instruction::SIToFP:
3436*9880d681SAndroid Build Coastguard Worker return X86SelectSIToFP(I);
3437*9880d681SAndroid Build Coastguard Worker case Instruction::IntToPtr: // Deliberate fall-through.
3438*9880d681SAndroid Build Coastguard Worker case Instruction::PtrToInt: {
3439*9880d681SAndroid Build Coastguard Worker EVT SrcVT = TLI.getValueType(DL, I->getOperand(0)->getType());
3440*9880d681SAndroid Build Coastguard Worker EVT DstVT = TLI.getValueType(DL, I->getType());
3441*9880d681SAndroid Build Coastguard Worker if (DstVT.bitsGT(SrcVT))
3442*9880d681SAndroid Build Coastguard Worker return X86SelectZExt(I);
3443*9880d681SAndroid Build Coastguard Worker if (DstVT.bitsLT(SrcVT))
3444*9880d681SAndroid Build Coastguard Worker return X86SelectTrunc(I);
3445*9880d681SAndroid Build Coastguard Worker unsigned Reg = getRegForValue(I->getOperand(0));
3446*9880d681SAndroid Build Coastguard Worker if (Reg == 0) return false;
3447*9880d681SAndroid Build Coastguard Worker updateValueMap(I, Reg);
3448*9880d681SAndroid Build Coastguard Worker return true;
3449*9880d681SAndroid Build Coastguard Worker }
3450*9880d681SAndroid Build Coastguard Worker case Instruction::BitCast: {
3451*9880d681SAndroid Build Coastguard Worker // Select SSE2/AVX bitcasts between 128/256 bit vector types.
3452*9880d681SAndroid Build Coastguard Worker if (!Subtarget->hasSSE2())
3453*9880d681SAndroid Build Coastguard Worker return false;
3454*9880d681SAndroid Build Coastguard Worker
3455*9880d681SAndroid Build Coastguard Worker EVT SrcVT = TLI.getValueType(DL, I->getOperand(0)->getType());
3456*9880d681SAndroid Build Coastguard Worker EVT DstVT = TLI.getValueType(DL, I->getType());
3457*9880d681SAndroid Build Coastguard Worker
3458*9880d681SAndroid Build Coastguard Worker if (!SrcVT.isSimple() || !DstVT.isSimple())
3459*9880d681SAndroid Build Coastguard Worker return false;
3460*9880d681SAndroid Build Coastguard Worker
3461*9880d681SAndroid Build Coastguard Worker if (!SrcVT.is128BitVector() &&
3462*9880d681SAndroid Build Coastguard Worker !(Subtarget->hasAVX() && SrcVT.is256BitVector()))
3463*9880d681SAndroid Build Coastguard Worker return false;
3464*9880d681SAndroid Build Coastguard Worker
3465*9880d681SAndroid Build Coastguard Worker unsigned Reg = getRegForValue(I->getOperand(0));
3466*9880d681SAndroid Build Coastguard Worker if (Reg == 0)
3467*9880d681SAndroid Build Coastguard Worker return false;
3468*9880d681SAndroid Build Coastguard Worker
3469*9880d681SAndroid Build Coastguard Worker // No instruction is needed for conversion. Reuse the register used by
3470*9880d681SAndroid Build Coastguard Worker // the fist operand.
3471*9880d681SAndroid Build Coastguard Worker updateValueMap(I, Reg);
3472*9880d681SAndroid Build Coastguard Worker return true;
3473*9880d681SAndroid Build Coastguard Worker }
3474*9880d681SAndroid Build Coastguard Worker }
3475*9880d681SAndroid Build Coastguard Worker
3476*9880d681SAndroid Build Coastguard Worker return false;
3477*9880d681SAndroid Build Coastguard Worker }
3478*9880d681SAndroid Build Coastguard Worker
X86MaterializeInt(const ConstantInt * CI,MVT VT)3479*9880d681SAndroid Build Coastguard Worker unsigned X86FastISel::X86MaterializeInt(const ConstantInt *CI, MVT VT) {
3480*9880d681SAndroid Build Coastguard Worker if (VT > MVT::i64)
3481*9880d681SAndroid Build Coastguard Worker return 0;
3482*9880d681SAndroid Build Coastguard Worker
3483*9880d681SAndroid Build Coastguard Worker uint64_t Imm = CI->getZExtValue();
3484*9880d681SAndroid Build Coastguard Worker if (Imm == 0) {
3485*9880d681SAndroid Build Coastguard Worker unsigned SrcReg = fastEmitInst_(X86::MOV32r0, &X86::GR32RegClass);
3486*9880d681SAndroid Build Coastguard Worker switch (VT.SimpleTy) {
3487*9880d681SAndroid Build Coastguard Worker default: llvm_unreachable("Unexpected value type");
3488*9880d681SAndroid Build Coastguard Worker case MVT::i1:
3489*9880d681SAndroid Build Coastguard Worker case MVT::i8:
3490*9880d681SAndroid Build Coastguard Worker return fastEmitInst_extractsubreg(MVT::i8, SrcReg, /*Kill=*/true,
3491*9880d681SAndroid Build Coastguard Worker X86::sub_8bit);
3492*9880d681SAndroid Build Coastguard Worker case MVT::i16:
3493*9880d681SAndroid Build Coastguard Worker return fastEmitInst_extractsubreg(MVT::i16, SrcReg, /*Kill=*/true,
3494*9880d681SAndroid Build Coastguard Worker X86::sub_16bit);
3495*9880d681SAndroid Build Coastguard Worker case MVT::i32:
3496*9880d681SAndroid Build Coastguard Worker return SrcReg;
3497*9880d681SAndroid Build Coastguard Worker case MVT::i64: {
3498*9880d681SAndroid Build Coastguard Worker unsigned ResultReg = createResultReg(&X86::GR64RegClass);
3499*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
3500*9880d681SAndroid Build Coastguard Worker TII.get(TargetOpcode::SUBREG_TO_REG), ResultReg)
3501*9880d681SAndroid Build Coastguard Worker .addImm(0).addReg(SrcReg).addImm(X86::sub_32bit);
3502*9880d681SAndroid Build Coastguard Worker return ResultReg;
3503*9880d681SAndroid Build Coastguard Worker }
3504*9880d681SAndroid Build Coastguard Worker }
3505*9880d681SAndroid Build Coastguard Worker }
3506*9880d681SAndroid Build Coastguard Worker
3507*9880d681SAndroid Build Coastguard Worker unsigned Opc = 0;
3508*9880d681SAndroid Build Coastguard Worker switch (VT.SimpleTy) {
3509*9880d681SAndroid Build Coastguard Worker default: llvm_unreachable("Unexpected value type");
3510*9880d681SAndroid Build Coastguard Worker case MVT::i1: VT = MVT::i8; // fall-through
3511*9880d681SAndroid Build Coastguard Worker case MVT::i8: Opc = X86::MOV8ri; break;
3512*9880d681SAndroid Build Coastguard Worker case MVT::i16: Opc = X86::MOV16ri; break;
3513*9880d681SAndroid Build Coastguard Worker case MVT::i32: Opc = X86::MOV32ri; break;
3514*9880d681SAndroid Build Coastguard Worker case MVT::i64: {
3515*9880d681SAndroid Build Coastguard Worker if (isUInt<32>(Imm))
3516*9880d681SAndroid Build Coastguard Worker Opc = X86::MOV32ri;
3517*9880d681SAndroid Build Coastguard Worker else if (isInt<32>(Imm))
3518*9880d681SAndroid Build Coastguard Worker Opc = X86::MOV64ri32;
3519*9880d681SAndroid Build Coastguard Worker else
3520*9880d681SAndroid Build Coastguard Worker Opc = X86::MOV64ri;
3521*9880d681SAndroid Build Coastguard Worker break;
3522*9880d681SAndroid Build Coastguard Worker }
3523*9880d681SAndroid Build Coastguard Worker }
3524*9880d681SAndroid Build Coastguard Worker if (VT == MVT::i64 && Opc == X86::MOV32ri) {
3525*9880d681SAndroid Build Coastguard Worker unsigned SrcReg = fastEmitInst_i(Opc, &X86::GR32RegClass, Imm);
3526*9880d681SAndroid Build Coastguard Worker unsigned ResultReg = createResultReg(&X86::GR64RegClass);
3527*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
3528*9880d681SAndroid Build Coastguard Worker TII.get(TargetOpcode::SUBREG_TO_REG), ResultReg)
3529*9880d681SAndroid Build Coastguard Worker .addImm(0).addReg(SrcReg).addImm(X86::sub_32bit);
3530*9880d681SAndroid Build Coastguard Worker return ResultReg;
3531*9880d681SAndroid Build Coastguard Worker }
3532*9880d681SAndroid Build Coastguard Worker return fastEmitInst_i(Opc, TLI.getRegClassFor(VT), Imm);
3533*9880d681SAndroid Build Coastguard Worker }
3534*9880d681SAndroid Build Coastguard Worker
X86MaterializeFP(const ConstantFP * CFP,MVT VT)3535*9880d681SAndroid Build Coastguard Worker unsigned X86FastISel::X86MaterializeFP(const ConstantFP *CFP, MVT VT) {
3536*9880d681SAndroid Build Coastguard Worker if (CFP->isNullValue())
3537*9880d681SAndroid Build Coastguard Worker return fastMaterializeFloatZero(CFP);
3538*9880d681SAndroid Build Coastguard Worker
3539*9880d681SAndroid Build Coastguard Worker // Can't handle alternate code models yet.
3540*9880d681SAndroid Build Coastguard Worker CodeModel::Model CM = TM.getCodeModel();
3541*9880d681SAndroid Build Coastguard Worker if (CM != CodeModel::Small && CM != CodeModel::Large)
3542*9880d681SAndroid Build Coastguard Worker return 0;
3543*9880d681SAndroid Build Coastguard Worker
3544*9880d681SAndroid Build Coastguard Worker // Get opcode and regclass of the output for the given load instruction.
3545*9880d681SAndroid Build Coastguard Worker unsigned Opc = 0;
3546*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = nullptr;
3547*9880d681SAndroid Build Coastguard Worker switch (VT.SimpleTy) {
3548*9880d681SAndroid Build Coastguard Worker default: return 0;
3549*9880d681SAndroid Build Coastguard Worker case MVT::f32:
3550*9880d681SAndroid Build Coastguard Worker if (X86ScalarSSEf32) {
3551*9880d681SAndroid Build Coastguard Worker Opc = Subtarget->hasAVX() ? X86::VMOVSSrm : X86::MOVSSrm;
3552*9880d681SAndroid Build Coastguard Worker RC = &X86::FR32RegClass;
3553*9880d681SAndroid Build Coastguard Worker } else {
3554*9880d681SAndroid Build Coastguard Worker Opc = X86::LD_Fp32m;
3555*9880d681SAndroid Build Coastguard Worker RC = &X86::RFP32RegClass;
3556*9880d681SAndroid Build Coastguard Worker }
3557*9880d681SAndroid Build Coastguard Worker break;
3558*9880d681SAndroid Build Coastguard Worker case MVT::f64:
3559*9880d681SAndroid Build Coastguard Worker if (X86ScalarSSEf64) {
3560*9880d681SAndroid Build Coastguard Worker Opc = Subtarget->hasAVX() ? X86::VMOVSDrm : X86::MOVSDrm;
3561*9880d681SAndroid Build Coastguard Worker RC = &X86::FR64RegClass;
3562*9880d681SAndroid Build Coastguard Worker } else {
3563*9880d681SAndroid Build Coastguard Worker Opc = X86::LD_Fp64m;
3564*9880d681SAndroid Build Coastguard Worker RC = &X86::RFP64RegClass;
3565*9880d681SAndroid Build Coastguard Worker }
3566*9880d681SAndroid Build Coastguard Worker break;
3567*9880d681SAndroid Build Coastguard Worker case MVT::f80:
3568*9880d681SAndroid Build Coastguard Worker // No f80 support yet.
3569*9880d681SAndroid Build Coastguard Worker return 0;
3570*9880d681SAndroid Build Coastguard Worker }
3571*9880d681SAndroid Build Coastguard Worker
3572*9880d681SAndroid Build Coastguard Worker // MachineConstantPool wants an explicit alignment.
3573*9880d681SAndroid Build Coastguard Worker unsigned Align = DL.getPrefTypeAlignment(CFP->getType());
3574*9880d681SAndroid Build Coastguard Worker if (Align == 0) {
3575*9880d681SAndroid Build Coastguard Worker // Alignment of vector types. FIXME!
3576*9880d681SAndroid Build Coastguard Worker Align = DL.getTypeAllocSize(CFP->getType());
3577*9880d681SAndroid Build Coastguard Worker }
3578*9880d681SAndroid Build Coastguard Worker
3579*9880d681SAndroid Build Coastguard Worker // x86-32 PIC requires a PIC base register for constant pools.
3580*9880d681SAndroid Build Coastguard Worker unsigned PICBase = 0;
3581*9880d681SAndroid Build Coastguard Worker unsigned char OpFlag = Subtarget->classifyLocalReference(nullptr);
3582*9880d681SAndroid Build Coastguard Worker if (OpFlag == X86II::MO_PIC_BASE_OFFSET)
3583*9880d681SAndroid Build Coastguard Worker PICBase = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
3584*9880d681SAndroid Build Coastguard Worker else if (OpFlag == X86II::MO_GOTOFF)
3585*9880d681SAndroid Build Coastguard Worker PICBase = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
3586*9880d681SAndroid Build Coastguard Worker else if (Subtarget->is64Bit() && TM.getCodeModel() == CodeModel::Small)
3587*9880d681SAndroid Build Coastguard Worker PICBase = X86::RIP;
3588*9880d681SAndroid Build Coastguard Worker
3589*9880d681SAndroid Build Coastguard Worker // Create the load from the constant pool.
3590*9880d681SAndroid Build Coastguard Worker unsigned CPI = MCP.getConstantPoolIndex(CFP, Align);
3591*9880d681SAndroid Build Coastguard Worker unsigned ResultReg = createResultReg(RC);
3592*9880d681SAndroid Build Coastguard Worker
3593*9880d681SAndroid Build Coastguard Worker if (CM == CodeModel::Large) {
3594*9880d681SAndroid Build Coastguard Worker unsigned AddrReg = createResultReg(&X86::GR64RegClass);
3595*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::MOV64ri),
3596*9880d681SAndroid Build Coastguard Worker AddrReg)
3597*9880d681SAndroid Build Coastguard Worker .addConstantPoolIndex(CPI, 0, OpFlag);
3598*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
3599*9880d681SAndroid Build Coastguard Worker TII.get(Opc), ResultReg);
3600*9880d681SAndroid Build Coastguard Worker addDirectMem(MIB, AddrReg);
3601*9880d681SAndroid Build Coastguard Worker MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
3602*9880d681SAndroid Build Coastguard Worker MachinePointerInfo::getConstantPool(*FuncInfo.MF),
3603*9880d681SAndroid Build Coastguard Worker MachineMemOperand::MOLoad, DL.getPointerSize(), Align);
3604*9880d681SAndroid Build Coastguard Worker MIB->addMemOperand(*FuncInfo.MF, MMO);
3605*9880d681SAndroid Build Coastguard Worker return ResultReg;
3606*9880d681SAndroid Build Coastguard Worker }
3607*9880d681SAndroid Build Coastguard Worker
3608*9880d681SAndroid Build Coastguard Worker addConstantPoolReference(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
3609*9880d681SAndroid Build Coastguard Worker TII.get(Opc), ResultReg),
3610*9880d681SAndroid Build Coastguard Worker CPI, PICBase, OpFlag);
3611*9880d681SAndroid Build Coastguard Worker return ResultReg;
3612*9880d681SAndroid Build Coastguard Worker }
3613*9880d681SAndroid Build Coastguard Worker
X86MaterializeGV(const GlobalValue * GV,MVT VT)3614*9880d681SAndroid Build Coastguard Worker unsigned X86FastISel::X86MaterializeGV(const GlobalValue *GV, MVT VT) {
3615*9880d681SAndroid Build Coastguard Worker // Can't handle alternate code models yet.
3616*9880d681SAndroid Build Coastguard Worker if (TM.getCodeModel() != CodeModel::Small)
3617*9880d681SAndroid Build Coastguard Worker return 0;
3618*9880d681SAndroid Build Coastguard Worker
3619*9880d681SAndroid Build Coastguard Worker // Materialize addresses with LEA/MOV instructions.
3620*9880d681SAndroid Build Coastguard Worker X86AddressMode AM;
3621*9880d681SAndroid Build Coastguard Worker if (X86SelectAddress(GV, AM)) {
3622*9880d681SAndroid Build Coastguard Worker // If the expression is just a basereg, then we're done, otherwise we need
3623*9880d681SAndroid Build Coastguard Worker // to emit an LEA.
3624*9880d681SAndroid Build Coastguard Worker if (AM.BaseType == X86AddressMode::RegBase &&
3625*9880d681SAndroid Build Coastguard Worker AM.IndexReg == 0 && AM.Disp == 0 && AM.GV == nullptr)
3626*9880d681SAndroid Build Coastguard Worker return AM.Base.Reg;
3627*9880d681SAndroid Build Coastguard Worker
3628*9880d681SAndroid Build Coastguard Worker unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT));
3629*9880d681SAndroid Build Coastguard Worker if (TM.getRelocationModel() == Reloc::Static &&
3630*9880d681SAndroid Build Coastguard Worker TLI.getPointerTy(DL) == MVT::i64) {
3631*9880d681SAndroid Build Coastguard Worker // The displacement code could be more than 32 bits away so we need to use
3632*9880d681SAndroid Build Coastguard Worker // an instruction with a 64 bit immediate
3633*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::MOV64ri),
3634*9880d681SAndroid Build Coastguard Worker ResultReg)
3635*9880d681SAndroid Build Coastguard Worker .addGlobalAddress(GV);
3636*9880d681SAndroid Build Coastguard Worker } else {
3637*9880d681SAndroid Build Coastguard Worker unsigned Opc =
3638*9880d681SAndroid Build Coastguard Worker TLI.getPointerTy(DL) == MVT::i32
3639*9880d681SAndroid Build Coastguard Worker ? (Subtarget->isTarget64BitILP32() ? X86::LEA64_32r : X86::LEA32r)
3640*9880d681SAndroid Build Coastguard Worker : X86::LEA64r;
3641*9880d681SAndroid Build Coastguard Worker addFullAddress(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
3642*9880d681SAndroid Build Coastguard Worker TII.get(Opc), ResultReg), AM);
3643*9880d681SAndroid Build Coastguard Worker }
3644*9880d681SAndroid Build Coastguard Worker return ResultReg;
3645*9880d681SAndroid Build Coastguard Worker }
3646*9880d681SAndroid Build Coastguard Worker return 0;
3647*9880d681SAndroid Build Coastguard Worker }
3648*9880d681SAndroid Build Coastguard Worker
fastMaterializeConstant(const Constant * C)3649*9880d681SAndroid Build Coastguard Worker unsigned X86FastISel::fastMaterializeConstant(const Constant *C) {
3650*9880d681SAndroid Build Coastguard Worker EVT CEVT = TLI.getValueType(DL, C->getType(), true);
3651*9880d681SAndroid Build Coastguard Worker
3652*9880d681SAndroid Build Coastguard Worker // Only handle simple types.
3653*9880d681SAndroid Build Coastguard Worker if (!CEVT.isSimple())
3654*9880d681SAndroid Build Coastguard Worker return 0;
3655*9880d681SAndroid Build Coastguard Worker MVT VT = CEVT.getSimpleVT();
3656*9880d681SAndroid Build Coastguard Worker
3657*9880d681SAndroid Build Coastguard Worker if (const auto *CI = dyn_cast<ConstantInt>(C))
3658*9880d681SAndroid Build Coastguard Worker return X86MaterializeInt(CI, VT);
3659*9880d681SAndroid Build Coastguard Worker else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C))
3660*9880d681SAndroid Build Coastguard Worker return X86MaterializeFP(CFP, VT);
3661*9880d681SAndroid Build Coastguard Worker else if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
3662*9880d681SAndroid Build Coastguard Worker return X86MaterializeGV(GV, VT);
3663*9880d681SAndroid Build Coastguard Worker
3664*9880d681SAndroid Build Coastguard Worker return 0;
3665*9880d681SAndroid Build Coastguard Worker }
3666*9880d681SAndroid Build Coastguard Worker
fastMaterializeAlloca(const AllocaInst * C)3667*9880d681SAndroid Build Coastguard Worker unsigned X86FastISel::fastMaterializeAlloca(const AllocaInst *C) {
3668*9880d681SAndroid Build Coastguard Worker // Fail on dynamic allocas. At this point, getRegForValue has already
3669*9880d681SAndroid Build Coastguard Worker // checked its CSE maps, so if we're here trying to handle a dynamic
3670*9880d681SAndroid Build Coastguard Worker // alloca, we're not going to succeed. X86SelectAddress has a
3671*9880d681SAndroid Build Coastguard Worker // check for dynamic allocas, because it's called directly from
3672*9880d681SAndroid Build Coastguard Worker // various places, but targetMaterializeAlloca also needs a check
3673*9880d681SAndroid Build Coastguard Worker // in order to avoid recursion between getRegForValue,
3674*9880d681SAndroid Build Coastguard Worker // X86SelectAddrss, and targetMaterializeAlloca.
3675*9880d681SAndroid Build Coastguard Worker if (!FuncInfo.StaticAllocaMap.count(C))
3676*9880d681SAndroid Build Coastguard Worker return 0;
3677*9880d681SAndroid Build Coastguard Worker assert(C->isStaticAlloca() && "dynamic alloca in the static alloca map?");
3678*9880d681SAndroid Build Coastguard Worker
3679*9880d681SAndroid Build Coastguard Worker X86AddressMode AM;
3680*9880d681SAndroid Build Coastguard Worker if (!X86SelectAddress(C, AM))
3681*9880d681SAndroid Build Coastguard Worker return 0;
3682*9880d681SAndroid Build Coastguard Worker unsigned Opc =
3683*9880d681SAndroid Build Coastguard Worker TLI.getPointerTy(DL) == MVT::i32
3684*9880d681SAndroid Build Coastguard Worker ? (Subtarget->isTarget64BitILP32() ? X86::LEA64_32r : X86::LEA32r)
3685*9880d681SAndroid Build Coastguard Worker : X86::LEA64r;
3686*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = TLI.getRegClassFor(TLI.getPointerTy(DL));
3687*9880d681SAndroid Build Coastguard Worker unsigned ResultReg = createResultReg(RC);
3688*9880d681SAndroid Build Coastguard Worker addFullAddress(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
3689*9880d681SAndroid Build Coastguard Worker TII.get(Opc), ResultReg), AM);
3690*9880d681SAndroid Build Coastguard Worker return ResultReg;
3691*9880d681SAndroid Build Coastguard Worker }
3692*9880d681SAndroid Build Coastguard Worker
fastMaterializeFloatZero(const ConstantFP * CF)3693*9880d681SAndroid Build Coastguard Worker unsigned X86FastISel::fastMaterializeFloatZero(const ConstantFP *CF) {
3694*9880d681SAndroid Build Coastguard Worker MVT VT;
3695*9880d681SAndroid Build Coastguard Worker if (!isTypeLegal(CF->getType(), VT))
3696*9880d681SAndroid Build Coastguard Worker return 0;
3697*9880d681SAndroid Build Coastguard Worker
3698*9880d681SAndroid Build Coastguard Worker // Get opcode and regclass for the given zero.
3699*9880d681SAndroid Build Coastguard Worker unsigned Opc = 0;
3700*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = nullptr;
3701*9880d681SAndroid Build Coastguard Worker switch (VT.SimpleTy) {
3702*9880d681SAndroid Build Coastguard Worker default: return 0;
3703*9880d681SAndroid Build Coastguard Worker case MVT::f32:
3704*9880d681SAndroid Build Coastguard Worker if (X86ScalarSSEf32) {
3705*9880d681SAndroid Build Coastguard Worker Opc = X86::FsFLD0SS;
3706*9880d681SAndroid Build Coastguard Worker RC = &X86::FR32RegClass;
3707*9880d681SAndroid Build Coastguard Worker } else {
3708*9880d681SAndroid Build Coastguard Worker Opc = X86::LD_Fp032;
3709*9880d681SAndroid Build Coastguard Worker RC = &X86::RFP32RegClass;
3710*9880d681SAndroid Build Coastguard Worker }
3711*9880d681SAndroid Build Coastguard Worker break;
3712*9880d681SAndroid Build Coastguard Worker case MVT::f64:
3713*9880d681SAndroid Build Coastguard Worker if (X86ScalarSSEf64) {
3714*9880d681SAndroid Build Coastguard Worker Opc = X86::FsFLD0SD;
3715*9880d681SAndroid Build Coastguard Worker RC = &X86::FR64RegClass;
3716*9880d681SAndroid Build Coastguard Worker } else {
3717*9880d681SAndroid Build Coastguard Worker Opc = X86::LD_Fp064;
3718*9880d681SAndroid Build Coastguard Worker RC = &X86::RFP64RegClass;
3719*9880d681SAndroid Build Coastguard Worker }
3720*9880d681SAndroid Build Coastguard Worker break;
3721*9880d681SAndroid Build Coastguard Worker case MVT::f80:
3722*9880d681SAndroid Build Coastguard Worker // No f80 support yet.
3723*9880d681SAndroid Build Coastguard Worker return 0;
3724*9880d681SAndroid Build Coastguard Worker }
3725*9880d681SAndroid Build Coastguard Worker
3726*9880d681SAndroid Build Coastguard Worker unsigned ResultReg = createResultReg(RC);
3727*9880d681SAndroid Build Coastguard Worker BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg);
3728*9880d681SAndroid Build Coastguard Worker return ResultReg;
3729*9880d681SAndroid Build Coastguard Worker }
3730*9880d681SAndroid Build Coastguard Worker
3731*9880d681SAndroid Build Coastguard Worker
tryToFoldLoadIntoMI(MachineInstr * MI,unsigned OpNo,const LoadInst * LI)3732*9880d681SAndroid Build Coastguard Worker bool X86FastISel::tryToFoldLoadIntoMI(MachineInstr *MI, unsigned OpNo,
3733*9880d681SAndroid Build Coastguard Worker const LoadInst *LI) {
3734*9880d681SAndroid Build Coastguard Worker const Value *Ptr = LI->getPointerOperand();
3735*9880d681SAndroid Build Coastguard Worker X86AddressMode AM;
3736*9880d681SAndroid Build Coastguard Worker if (!X86SelectAddress(Ptr, AM))
3737*9880d681SAndroid Build Coastguard Worker return false;
3738*9880d681SAndroid Build Coastguard Worker
3739*9880d681SAndroid Build Coastguard Worker const X86InstrInfo &XII = (const X86InstrInfo &)TII;
3740*9880d681SAndroid Build Coastguard Worker
3741*9880d681SAndroid Build Coastguard Worker unsigned Size = DL.getTypeAllocSize(LI->getType());
3742*9880d681SAndroid Build Coastguard Worker unsigned Alignment = LI->getAlignment();
3743*9880d681SAndroid Build Coastguard Worker
3744*9880d681SAndroid Build Coastguard Worker if (Alignment == 0) // Ensure that codegen never sees alignment 0
3745*9880d681SAndroid Build Coastguard Worker Alignment = DL.getABITypeAlignment(LI->getType());
3746*9880d681SAndroid Build Coastguard Worker
3747*9880d681SAndroid Build Coastguard Worker SmallVector<MachineOperand, 8> AddrOps;
3748*9880d681SAndroid Build Coastguard Worker AM.getFullAddress(AddrOps);
3749*9880d681SAndroid Build Coastguard Worker
3750*9880d681SAndroid Build Coastguard Worker MachineInstr *Result = XII.foldMemoryOperandImpl(
3751*9880d681SAndroid Build Coastguard Worker *FuncInfo.MF, *MI, OpNo, AddrOps, FuncInfo.InsertPt, Size, Alignment,
3752*9880d681SAndroid Build Coastguard Worker /*AllowCommute=*/true);
3753*9880d681SAndroid Build Coastguard Worker if (!Result)
3754*9880d681SAndroid Build Coastguard Worker return false;
3755*9880d681SAndroid Build Coastguard Worker
3756*9880d681SAndroid Build Coastguard Worker // The index register could be in the wrong register class. Unfortunately,
3757*9880d681SAndroid Build Coastguard Worker // foldMemoryOperandImpl could have commuted the instruction so its not enough
3758*9880d681SAndroid Build Coastguard Worker // to just look at OpNo + the offset to the index reg. We actually need to
3759*9880d681SAndroid Build Coastguard Worker // scan the instruction to find the index reg and see if its the correct reg
3760*9880d681SAndroid Build Coastguard Worker // class.
3761*9880d681SAndroid Build Coastguard Worker unsigned OperandNo = 0;
3762*9880d681SAndroid Build Coastguard Worker for (MachineInstr::mop_iterator I = Result->operands_begin(),
3763*9880d681SAndroid Build Coastguard Worker E = Result->operands_end(); I != E; ++I, ++OperandNo) {
3764*9880d681SAndroid Build Coastguard Worker MachineOperand &MO = *I;
3765*9880d681SAndroid Build Coastguard Worker if (!MO.isReg() || MO.isDef() || MO.getReg() != AM.IndexReg)
3766*9880d681SAndroid Build Coastguard Worker continue;
3767*9880d681SAndroid Build Coastguard Worker // Found the index reg, now try to rewrite it.
3768*9880d681SAndroid Build Coastguard Worker unsigned IndexReg = constrainOperandRegClass(Result->getDesc(),
3769*9880d681SAndroid Build Coastguard Worker MO.getReg(), OperandNo);
3770*9880d681SAndroid Build Coastguard Worker if (IndexReg == MO.getReg())
3771*9880d681SAndroid Build Coastguard Worker continue;
3772*9880d681SAndroid Build Coastguard Worker MO.setReg(IndexReg);
3773*9880d681SAndroid Build Coastguard Worker }
3774*9880d681SAndroid Build Coastguard Worker
3775*9880d681SAndroid Build Coastguard Worker Result->addMemOperand(*FuncInfo.MF, createMachineMemOperandFor(LI));
3776*9880d681SAndroid Build Coastguard Worker MI->eraseFromParent();
3777*9880d681SAndroid Build Coastguard Worker return true;
3778*9880d681SAndroid Build Coastguard Worker }
3779*9880d681SAndroid Build Coastguard Worker
3780*9880d681SAndroid Build Coastguard Worker
3781*9880d681SAndroid Build Coastguard Worker namespace llvm {
createFastISel(FunctionLoweringInfo & funcInfo,const TargetLibraryInfo * libInfo)3782*9880d681SAndroid Build Coastguard Worker FastISel *X86::createFastISel(FunctionLoweringInfo &funcInfo,
3783*9880d681SAndroid Build Coastguard Worker const TargetLibraryInfo *libInfo) {
3784*9880d681SAndroid Build Coastguard Worker return new X86FastISel(funcInfo, libInfo);
3785*9880d681SAndroid Build Coastguard Worker }
3786*9880d681SAndroid Build Coastguard Worker }
3787