Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(91)

Side by Side Diff: src/IceTargetLoweringX8632.h

Issue 1202533003: Extracts an TargetX86Base target which will be used as the common X86{32,64} implementation. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Addresses comments. Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceInst.h ('k') | src/IceTargetLoweringX8632.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceTargetLoweringX8632.h - x86-32 lowering ---*- C++ -*-===// 1 //===- subzero/src/IceTargetLoweringX8632.h - x86-32 lowering ---*- C++ -*-===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // This file declares the TargetLoweringX8632 class, which 10 // This file declares the TargetLoweringX8632 class, which
11 // implements the TargetLowering interface for the x86-32 11 // implements the TargetLowering interface for the x86-32
12 // architecture. 12 // architecture.
13 // 13 //
14 //===----------------------------------------------------------------------===// 14 //===----------------------------------------------------------------------===//
15 15
16 #ifndef SUBZERO_SRC_ICETARGETLOWERINGX8632_H 16 #ifndef SUBZERO_SRC_ICETARGETLOWERINGX8632_H
17 #define SUBZERO_SRC_ICETARGETLOWERINGX8632_H 17 #define SUBZERO_SRC_ICETARGETLOWERINGX8632_H
18 18
19 #include <unordered_map>
20
21 #include "IceAssemblerX8632.h" 19 #include "IceAssemblerX8632.h"
22 #include "IceDefs.h" 20 #include "IceDefs.h"
23 #include "IceInst.h"
24 #include "IceInstX8632.h" 21 #include "IceInstX8632.h"
25 #include "IceRegistersX8632.h" 22 #include "IceRegistersX8632.h"
26 #include "IceTargetLowering.h" 23 #include "IceTargetLowering.h"
27 24
28 namespace Ice { 25 namespace Ice {
29 26
30 class BoolFoldingEntry { 27 class Cfg;
Jim Stichnoth 2015/06/23 17:24:33 These are already forward-declared in IceDefs.h.
John 2015/06/23 17:52:50 IceDefs..... :( Done.
31 BoolFoldingEntry(const BoolFoldingEntry &) = delete; 28 class GlobalContext;
32
33 public:
34 BoolFoldingEntry() = default;
35 explicit BoolFoldingEntry(Inst *I);
36 BoolFoldingEntry &operator=(const BoolFoldingEntry &) = default;
37 // Instr is the instruction producing the i1-type variable of interest.
38 Inst *Instr = nullptr;
39 // IsComplex is the cached result of BoolFolding::hasComplexLowering(Instr).
40 bool IsComplex = false;
41 // IsLiveOut is initialized conservatively to true, and is set to false when
42 // we encounter an instruction that ends Var's live range. We disable the
43 // folding optimization when Var is live beyond this basic block. Note that
44 // if liveness analysis is not performed (e.g. in Om1 mode), IsLiveOut will
45 // always be true and the folding optimization will never be performed.
46 bool IsLiveOut = true;
47 // NumUses counts the number of times Var is used as a source operand in the
48 // basic block. If IsComplex is true and there is more than one use of Var,
49 // then the folding optimization is disabled for Var.
50 uint32_t NumUses = 0;
51 };
52
53 class BoolFolding {
54 public:
55 enum BoolFoldingProducerKind {
56 PK_None,
57 PK_Icmp32,
58 PK_Icmp64,
59 PK_Fcmp,
60 PK_Trunc
61 };
62
63 // Currently the actual enum values are not used (other than CK_None), but we
64 // go
65 // ahead and produce them anyway for symmetry with the
66 // BoolFoldingProducerKind.
67 enum BoolFoldingConsumerKind { CK_None, CK_Br, CK_Select, CK_Sext, CK_Zext };
68
69 private:
70 BoolFolding(const BoolFolding &) = delete;
71 BoolFolding &operator=(const BoolFolding &) = delete;
72
73 public:
74 BoolFolding() = default;
75 static BoolFoldingProducerKind getProducerKind(const Inst *Instr);
76 static BoolFoldingConsumerKind getConsumerKind(const Inst *Instr);
77 static bool hasComplexLowering(const Inst *Instr);
78 void init(CfgNode *Node);
79 const Inst *getProducerFor(const Operand *Opnd) const;
80 void dump(const Cfg *Func) const;
81
82 private:
83 // Returns true if Producers contains a valid entry for the given VarNum.
84 bool containsValid(SizeT VarNum) const {
85 auto Element = Producers.find(VarNum);
86 return Element != Producers.end() && Element->second.Instr != nullptr;
87 }
88 void setInvalid(SizeT VarNum) { Producers[VarNum].Instr = nullptr; }
89 // Producers maps Variable::Number to a BoolFoldingEntry.
90 std::unordered_map<SizeT, BoolFoldingEntry> Producers;
91 };
92 29
93 class TargetX8632 : public TargetLowering { 30 class TargetX8632 : public TargetLowering {
94 TargetX8632() = delete; 31 TargetX8632() = delete;
95 TargetX8632(const TargetX8632 &) = delete; 32 TargetX8632(const TargetX8632 &) = delete;
96 TargetX8632 &operator=(const TargetX8632 &) = delete; 33 TargetX8632 &operator=(const TargetX8632 &) = delete;
97 34
98 public: 35 public:
99 static TargetX8632 *create(Cfg *Func) { return new TargetX8632(Func); }
100
101 void translateOm1() override;
102 void translateO2() override;
103 void doLoadOpt();
104 bool doBranchOpt(Inst *I, const CfgNode *NextNode) override;
105
106 SizeT getNumRegisters() const override { return RegX8632::Reg_NUM; }
107 Variable *getPhysicalRegister(SizeT RegNum, Type Ty = IceType_void) override;
108 IceString getRegName(SizeT RegNum, Type Ty) const override;
109 llvm::SmallBitVector getRegisterSet(RegSetMask Include,
110 RegSetMask Exclude) const override;
111 const llvm::SmallBitVector &getRegisterSetForType(Type Ty) const override {
112 return TypeToRegisterSet[Ty];
113 }
114 bool hasFramePointer() const override { return IsEbpBasedFrame; }
115 SizeT getFrameOrStackReg() const override {
116 return IsEbpBasedFrame ? RegX8632::Reg_ebp : RegX8632::Reg_esp;
117 }
118 size_t typeWidthInBytesOnStack(Type Ty) const override {
119 // Round up to the next multiple of 4 bytes. In particular, i1,
120 // i8, and i16 are rounded up to 4 bytes.
121 return (typeWidthInBytes(Ty) + 3) & ~3;
122 }
123
124 void emitVariable(const Variable *Var) const override;
125
126 const char *getConstantPrefix() const final { return "$"; }
127 void emit(const ConstantUndef *C) const final;
128 void emit(const ConstantInteger32 *C) const final;
129 void emit(const ConstantInteger64 *C) const final;
130 void emit(const ConstantFloat *C) const final;
131 void emit(const ConstantDouble *C) const final;
132
133 void lowerArguments() override;
134 void initNodeForLowering(CfgNode *Node) override;
135 void addProlog(CfgNode *Node) override;
136 void addEpilog(CfgNode *Node) override;
137 // Ensure that a 64-bit Variable has been split into 2 32-bit
138 // Variables, creating them if necessary. This is needed for all
139 // I64 operations, and it is needed for pushing F64 arguments for
140 // function calls using the 32-bit push instruction (though the
141 // latter could be done by directly writing to the stack).
142 void split64(Variable *Var);
143 Operand *loOperand(Operand *Operand);
144 Operand *hiOperand(Operand *Operand);
145 void finishArgumentLowering(Variable *Arg, Variable *FramePtr,
146 size_t BasicFrameOffset, size_t &InArgsSizeBytes);
147 X8632::Address stackVarToAsmOperand(const Variable *Var) const;
148
149 enum X86InstructionSet { 36 enum X86InstructionSet {
150 Begin, 37 Begin,
151 // SSE2 is the PNaCl baseline instruction set. 38 // SSE2 is the PNaCl baseline instruction set.
152 SSE2 = Begin, 39 SSE2 = Begin,
153 SSE4_1, 40 SSE4_1,
154 End 41 End
155 }; 42 };
156 43
157 X86InstructionSet getInstructionSet() const { return InstructionSet; } 44 static TargetX8632 *create(Cfg *Func);
45 virtual X8632::Address stackVarToAsmOperand(const Variable *Var) const = 0;
46 virtual X86InstructionSet getInstructionSet() const = 0;
158 47
159 protected: 48 protected:
160 explicit TargetX8632(Cfg *Func); 49 explicit TargetX8632(Cfg *Func) : TargetLowering(Func) {}
161
162 void postLower() override;
163
164 void lowerAlloca(const InstAlloca *Inst) override;
165 void lowerArithmetic(const InstArithmetic *Inst) override;
166 void lowerAssign(const InstAssign *Inst) override;
167 void lowerBr(const InstBr *Inst) override;
168 void lowerCall(const InstCall *Inst) override;
169 void lowerCast(const InstCast *Inst) override;
170 void lowerExtractElement(const InstExtractElement *Inst) override;
171 void lowerFcmp(const InstFcmp *Inst) override;
172 void lowerIcmp(const InstIcmp *Inst) override;
173 void lowerIntrinsicCall(const InstIntrinsicCall *Inst) override;
174 void lowerInsertElement(const InstInsertElement *Inst) override;
175 void lowerLoad(const InstLoad *Inst) override;
176 void lowerPhi(const InstPhi *Inst) override;
177 void lowerRet(const InstRet *Inst) override;
178 void lowerSelect(const InstSelect *Inst) override;
179 void lowerStore(const InstStore *Inst) override;
180 void lowerSwitch(const InstSwitch *Inst) override;
181 void lowerUnreachable(const InstUnreachable *Inst) override;
182 void lowerOther(const Inst *Instr) override;
183 void lowerRMW(const InstX8632FakeRMW *RMW);
184 void prelowerPhis() override;
185 void lowerPhiAssignments(CfgNode *Node,
186 const AssignList &Assignments) override;
187 void doAddressOptLoad() override;
188 void doAddressOptStore() override;
189 void randomlyInsertNop(float Probability) override;
190
191 // Naive lowering of cmpxchg.
192 void lowerAtomicCmpxchg(Variable *DestPrev, Operand *Ptr, Operand *Expected,
193 Operand *Desired);
194 // Attempt a more optimized lowering of cmpxchg. Returns true if optimized.
195 bool tryOptimizedCmpxchgCmpBr(Variable *DestPrev, Operand *Ptr,
196 Operand *Expected, Operand *Desired);
197 void lowerAtomicRMW(Variable *Dest, uint32_t Operation, Operand *Ptr,
198 Operand *Val);
199 void lowerCountZeros(bool Cttz, Type Ty, Variable *Dest, Operand *FirstVal,
200 Operand *SecondVal);
201
202 typedef void (TargetX8632::*LowerBinOp)(Variable *, Operand *);
203 void expandAtomicRMWAsCmpxchg(LowerBinOp op_lo, LowerBinOp op_hi,
204 Variable *Dest, Operand *Ptr, Operand *Val);
205
206 void eliminateNextVectorSextInstruction(Variable *SignExtendedResult);
207
208 void scalarizeArithmetic(InstArithmetic::OpKind K, Variable *Dest,
209 Operand *Src0, Operand *Src1);
210
211 // Operand legalization helpers. To deal with address mode
212 // constraints, the helpers will create a new Operand and emit
213 // instructions that guarantee that the Operand kind is one of those
214 // indicated by the LegalMask (a bitmask of allowed kinds). If the
215 // input Operand is known to already meet the constraints, it may be
216 // simply returned as the result, without creating any new
217 // instructions or operands.
218 enum OperandLegalization {
219 Legal_None = 0,
220 Legal_Reg = 1 << 0, // physical register, not stack location
221 Legal_Imm = 1 << 1,
222 Legal_Mem = 1 << 2, // includes [eax+4*ecx] as well as [esp+12]
223 Legal_All = ~Legal_None
224 };
225 typedef uint32_t LegalMask;
226 Operand *legalize(Operand *From, LegalMask Allowed = Legal_All,
227 int32_t RegNum = Variable::NoRegister);
228 Variable *legalizeToVar(Operand *From, int32_t RegNum = Variable::NoRegister);
229 // Legalize the first source operand for use in the cmp instruction.
230 Operand *legalizeSrc0ForCmp(Operand *Src0, Operand *Src1);
231 // Turn a pointer operand into a memory operand that can be
232 // used by a real load/store operation. Legalizes the operand as well.
233 // This is a nop if the operand is already a legal memory operand.
234 OperandX8632Mem *formMemoryOperand(Operand *Ptr, Type Ty,
235 bool DoLegalize = true);
236
237 Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister);
238 static Type stackSlotType();
239
240 Variable *copyToReg(Operand *Src, int32_t RegNum = Variable::NoRegister);
241
242 // Returns a vector in a register with the given constant entries.
243 Variable *makeVectorOfZeros(Type Ty, int32_t RegNum = Variable::NoRegister);
244 Variable *makeVectorOfOnes(Type Ty, int32_t RegNum = Variable::NoRegister);
245 Variable *makeVectorOfMinusOnes(Type Ty,
246 int32_t RegNum = Variable::NoRegister);
247 Variable *makeVectorOfHighOrderBits(Type Ty,
248 int32_t RegNum = Variable::NoRegister);
249 Variable *makeVectorOfFabsMask(Type Ty,
250 int32_t RegNum = Variable::NoRegister);
251
252 // Return a memory operand corresponding to a stack allocated Variable.
253 OperandX8632Mem *getMemoryOperandForStackSlot(Type Ty, Variable *Slot,
254 uint32_t Offset = 0);
255
256 void makeRandomRegisterPermutation(
257 llvm::SmallVectorImpl<int32_t> &Permutation,
258 const llvm::SmallBitVector &ExcludeRegisters) const override;
259
260 // The following are helpers that insert lowered x86 instructions
261 // with minimal syntactic overhead, so that the lowering code can
262 // look as close to assembly as practical.
263 void _adc(Variable *Dest, Operand *Src0) {
264 Context.insert(InstX8632Adc::create(Func, Dest, Src0));
265 }
266 void _adc_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) {
267 Context.insert(InstX8632AdcRMW::create(Func, DestSrc0, Src1));
268 }
269 void _add(Variable *Dest, Operand *Src0) {
270 Context.insert(InstX8632Add::create(Func, Dest, Src0));
271 }
272 void _add_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) {
273 Context.insert(InstX8632AddRMW::create(Func, DestSrc0, Src1));
274 }
275 void _adjust_stack(int32_t Amount) {
276 Context.insert(InstX8632AdjustStack::create(
277 Func, Amount, getPhysicalRegister(RegX8632::Reg_esp)));
278 }
279 void _addps(Variable *Dest, Operand *Src0) {
280 Context.insert(InstX8632Addps::create(Func, Dest, Src0));
281 }
282 void _addss(Variable *Dest, Operand *Src0) {
283 Context.insert(InstX8632Addss::create(Func, Dest, Src0));
284 }
285 void _and(Variable *Dest, Operand *Src0) {
286 Context.insert(InstX8632And::create(Func, Dest, Src0));
287 }
288 void _and_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) {
289 Context.insert(InstX8632AndRMW::create(Func, DestSrc0, Src1));
290 }
291 void _blendvps(Variable *Dest, Operand *Src0, Operand *Src1) {
292 Context.insert(InstX8632Blendvps::create(Func, Dest, Src0, Src1));
293 }
294 void _br(CondX86::BrCond Condition, CfgNode *TargetTrue,
295 CfgNode *TargetFalse) {
296 Context.insert(
297 InstX8632Br::create(Func, TargetTrue, TargetFalse, Condition));
298 }
299 void _br(CfgNode *Target) {
300 Context.insert(InstX8632Br::create(Func, Target));
301 }
302 void _br(CondX86::BrCond Condition, CfgNode *Target) {
303 Context.insert(InstX8632Br::create(Func, Target, Condition));
304 }
305 void _br(CondX86::BrCond Condition, InstX8632Label *Label) {
306 Context.insert(InstX8632Br::create(Func, Label, Condition));
307 }
308 void _bsf(Variable *Dest, Operand *Src0) {
309 Context.insert(InstX8632Bsf::create(Func, Dest, Src0));
310 }
311 void _bsr(Variable *Dest, Operand *Src0) {
312 Context.insert(InstX8632Bsr::create(Func, Dest, Src0));
313 }
314 void _bswap(Variable *SrcDest) {
315 Context.insert(InstX8632Bswap::create(Func, SrcDest));
316 }
317 void _cbwdq(Variable *Dest, Operand *Src0) {
318 Context.insert(InstX8632Cbwdq::create(Func, Dest, Src0));
319 }
320 void _cmov(Variable *Dest, Operand *Src0, CondX86::BrCond Condition) {
321 Context.insert(InstX8632Cmov::create(Func, Dest, Src0, Condition));
322 }
323 void _cmp(Operand *Src0, Operand *Src1) {
324 Context.insert(InstX8632Icmp::create(Func, Src0, Src1));
325 }
326 void _cmpps(Variable *Dest, Operand *Src0, CondX86::CmppsCond Condition) {
327 Context.insert(InstX8632Cmpps::create(Func, Dest, Src0, Condition));
328 }
329 void _cmpxchg(Operand *DestOrAddr, Variable *Eax, Variable *Desired,
330 bool Locked) {
331 Context.insert(
332 InstX8632Cmpxchg::create(Func, DestOrAddr, Eax, Desired, Locked));
333 // Mark eax as possibly modified by cmpxchg.
334 Context.insert(
335 InstFakeDef::create(Func, Eax, llvm::dyn_cast<Variable>(DestOrAddr)));
336 _set_dest_nonkillable();
337 Context.insert(InstFakeUse::create(Func, Eax));
338 }
339 void _cmpxchg8b(OperandX8632Mem *Addr, Variable *Edx, Variable *Eax,
340 Variable *Ecx, Variable *Ebx, bool Locked) {
341 Context.insert(
342 InstX8632Cmpxchg8b::create(Func, Addr, Edx, Eax, Ecx, Ebx, Locked));
343 // Mark edx, and eax as possibly modified by cmpxchg8b.
344 Context.insert(InstFakeDef::create(Func, Edx));
345 _set_dest_nonkillable();
346 Context.insert(InstFakeUse::create(Func, Edx));
347 Context.insert(InstFakeDef::create(Func, Eax));
348 _set_dest_nonkillable();
349 Context.insert(InstFakeUse::create(Func, Eax));
350 }
351 void _cvt(Variable *Dest, Operand *Src0, InstX8632Cvt::CvtVariant Variant) {
352 Context.insert(InstX8632Cvt::create(Func, Dest, Src0, Variant));
353 }
354 void _div(Variable *Dest, Operand *Src0, Operand *Src1) {
355 Context.insert(InstX8632Div::create(Func, Dest, Src0, Src1));
356 }
357 void _divps(Variable *Dest, Operand *Src0) {
358 Context.insert(InstX8632Divps::create(Func, Dest, Src0));
359 }
360 void _divss(Variable *Dest, Operand *Src0) {
361 Context.insert(InstX8632Divss::create(Func, Dest, Src0));
362 }
363 void _fld(Operand *Src0) { Context.insert(InstX8632Fld::create(Func, Src0)); }
364 void _fstp(Variable *Dest) {
365 Context.insert(InstX8632Fstp::create(Func, Dest));
366 }
367 void _idiv(Variable *Dest, Operand *Src0, Operand *Src1) {
368 Context.insert(InstX8632Idiv::create(Func, Dest, Src0, Src1));
369 }
370 void _imul(Variable *Dest, Operand *Src0) {
371 Context.insert(InstX8632Imul::create(Func, Dest, Src0));
372 }
373 void _insertps(Variable *Dest, Operand *Src0, Operand *Src1) {
374 Context.insert(InstX8632Insertps::create(Func, Dest, Src0, Src1));
375 }
376 void _jmp(Operand *Target) {
377 Context.insert(InstX8632Jmp::create(Func, Target));
378 }
379 void _lea(Variable *Dest, Operand *Src0) {
380 Context.insert(InstX8632Lea::create(Func, Dest, Src0));
381 }
382 void _mfence() { Context.insert(InstX8632Mfence::create(Func)); }
383 // If Dest=nullptr is passed in, then a new variable is created,
384 // marked as infinite register allocation weight, and returned
385 // through the in/out Dest argument.
386 void _mov(Variable *&Dest, Operand *Src0,
387 int32_t RegNum = Variable::NoRegister) {
388 if (Dest == nullptr)
389 Dest = makeReg(Src0->getType(), RegNum);
390 Context.insert(InstX8632Mov::create(Func, Dest, Src0));
391 }
392 void _mov_nonkillable(Variable *Dest, Operand *Src0) {
393 Inst *NewInst = InstX8632Mov::create(Func, Dest, Src0);
394 NewInst->setDestNonKillable();
395 Context.insert(NewInst);
396 }
397 void _movd(Variable *Dest, Operand *Src0) {
398 Context.insert(InstX8632Movd::create(Func, Dest, Src0));
399 }
400 void _movp(Variable *Dest, Operand *Src0) {
401 Context.insert(InstX8632Movp::create(Func, Dest, Src0));
402 }
403 void _movq(Variable *Dest, Operand *Src0) {
404 Context.insert(InstX8632Movq::create(Func, Dest, Src0));
405 }
406 void _movss(Variable *Dest, Variable *Src0) {
407 Context.insert(InstX8632MovssRegs::create(Func, Dest, Src0));
408 }
409 void _movsx(Variable *Dest, Operand *Src0) {
410 Context.insert(InstX8632Movsx::create(Func, Dest, Src0));
411 }
412 void _movzx(Variable *Dest, Operand *Src0) {
413 Context.insert(InstX8632Movzx::create(Func, Dest, Src0));
414 }
415 void _mul(Variable *Dest, Variable *Src0, Operand *Src1) {
416 Context.insert(InstX8632Mul::create(Func, Dest, Src0, Src1));
417 }
418 void _mulps(Variable *Dest, Operand *Src0) {
419 Context.insert(InstX8632Mulps::create(Func, Dest, Src0));
420 }
421 void _mulss(Variable *Dest, Operand *Src0) {
422 Context.insert(InstX8632Mulss::create(Func, Dest, Src0));
423 }
424 void _neg(Variable *SrcDest) {
425 Context.insert(InstX8632Neg::create(Func, SrcDest));
426 }
427 void _nop(SizeT Variant) {
428 Context.insert(InstX8632Nop::create(Func, Variant));
429 }
430 void _or(Variable *Dest, Operand *Src0) {
431 Context.insert(InstX8632Or::create(Func, Dest, Src0));
432 }
433 void _or_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) {
434 Context.insert(InstX8632OrRMW::create(Func, DestSrc0, Src1));
435 }
436 void _padd(Variable *Dest, Operand *Src0) {
437 Context.insert(InstX8632Padd::create(Func, Dest, Src0));
438 }
439 void _pand(Variable *Dest, Operand *Src0) {
440 Context.insert(InstX8632Pand::create(Func, Dest, Src0));
441 }
442 void _pandn(Variable *Dest, Operand *Src0) {
443 Context.insert(InstX8632Pandn::create(Func, Dest, Src0));
444 }
445 void _pblendvb(Variable *Dest, Operand *Src0, Operand *Src1) {
446 Context.insert(InstX8632Pblendvb::create(Func, Dest, Src0, Src1));
447 }
448 void _pcmpeq(Variable *Dest, Operand *Src0) {
449 Context.insert(InstX8632Pcmpeq::create(Func, Dest, Src0));
450 }
451 void _pcmpgt(Variable *Dest, Operand *Src0) {
452 Context.insert(InstX8632Pcmpgt::create(Func, Dest, Src0));
453 }
454 void _pextr(Variable *Dest, Operand *Src0, Operand *Src1) {
455 Context.insert(InstX8632Pextr::create(Func, Dest, Src0, Src1));
456 }
457 void _pinsr(Variable *Dest, Operand *Src0, Operand *Src1) {
458 Context.insert(InstX8632Pinsr::create(Func, Dest, Src0, Src1));
459 }
460 void _pmull(Variable *Dest, Operand *Src0) {
461 Context.insert(InstX8632Pmull::create(Func, Dest, Src0));
462 }
463 void _pmuludq(Variable *Dest, Operand *Src0) {
464 Context.insert(InstX8632Pmuludq::create(Func, Dest, Src0));
465 }
466 void _pop(Variable *Dest) {
467 Context.insert(InstX8632Pop::create(Func, Dest));
468 }
469 void _por(Variable *Dest, Operand *Src0) {
470 Context.insert(InstX8632Por::create(Func, Dest, Src0));
471 }
472 void _pshufd(Variable *Dest, Operand *Src0, Operand *Src1) {
473 Context.insert(InstX8632Pshufd::create(Func, Dest, Src0, Src1));
474 }
475 void _psll(Variable *Dest, Operand *Src0) {
476 Context.insert(InstX8632Psll::create(Func, Dest, Src0));
477 }
478 void _psra(Variable *Dest, Operand *Src0) {
479 Context.insert(InstX8632Psra::create(Func, Dest, Src0));
480 }
481 void _psrl(Variable *Dest, Operand *Src0) {
482 Context.insert(InstX8632Psrl::create(Func, Dest, Src0));
483 }
484 void _psub(Variable *Dest, Operand *Src0) {
485 Context.insert(InstX8632Psub::create(Func, Dest, Src0));
486 }
487 void _push(Variable *Src0) {
488 Context.insert(InstX8632Push::create(Func, Src0));
489 }
490 void _pxor(Variable *Dest, Operand *Src0) {
491 Context.insert(InstX8632Pxor::create(Func, Dest, Src0));
492 }
493 void _ret(Variable *Src0 = nullptr) {
494 Context.insert(InstX8632Ret::create(Func, Src0));
495 }
496 void _rol(Variable *Dest, Operand *Src0) {
497 Context.insert(InstX8632Rol::create(Func, Dest, Src0));
498 }
499 void _sar(Variable *Dest, Operand *Src0) {
500 Context.insert(InstX8632Sar::create(Func, Dest, Src0));
501 }
502 void _sbb(Variable *Dest, Operand *Src0) {
503 Context.insert(InstX8632Sbb::create(Func, Dest, Src0));
504 }
505 void _sbb_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) {
506 Context.insert(InstX8632SbbRMW::create(Func, DestSrc0, Src1));
507 }
508 void _setcc(Variable *Dest, CondX86::BrCond Condition) {
509 Context.insert(InstX8632Setcc::create(Func, Dest, Condition));
510 }
511 void _shl(Variable *Dest, Operand *Src0) {
512 Context.insert(InstX8632Shl::create(Func, Dest, Src0));
513 }
514 void _shld(Variable *Dest, Variable *Src0, Variable *Src1) {
515 Context.insert(InstX8632Shld::create(Func, Dest, Src0, Src1));
516 }
517 void _shr(Variable *Dest, Operand *Src0) {
518 Context.insert(InstX8632Shr::create(Func, Dest, Src0));
519 }
520 void _shrd(Variable *Dest, Variable *Src0, Variable *Src1) {
521 Context.insert(InstX8632Shrd::create(Func, Dest, Src0, Src1));
522 }
523 void _shufps(Variable *Dest, Operand *Src0, Operand *Src1) {
524 Context.insert(InstX8632Shufps::create(Func, Dest, Src0, Src1));
525 }
526 void _sqrtss(Variable *Dest, Operand *Src0) {
527 Context.insert(InstX8632Sqrtss::create(Func, Dest, Src0));
528 }
529 void _store(Operand *Value, OperandX8632 *Mem) {
530 Context.insert(InstX8632Store::create(Func, Value, Mem));
531 }
532 void _storep(Variable *Value, OperandX8632Mem *Mem) {
533 Context.insert(InstX8632StoreP::create(Func, Value, Mem));
534 }
535 void _storeq(Variable *Value, OperandX8632Mem *Mem) {
536 Context.insert(InstX8632StoreQ::create(Func, Value, Mem));
537 }
538 void _sub(Variable *Dest, Operand *Src0) {
539 Context.insert(InstX8632Sub::create(Func, Dest, Src0));
540 }
541 void _sub_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) {
542 Context.insert(InstX8632SubRMW::create(Func, DestSrc0, Src1));
543 }
544 void _subps(Variable *Dest, Operand *Src0) {
545 Context.insert(InstX8632Subps::create(Func, Dest, Src0));
546 }
547 void _subss(Variable *Dest, Operand *Src0) {
548 Context.insert(InstX8632Subss::create(Func, Dest, Src0));
549 }
550 void _test(Operand *Src0, Operand *Src1) {
551 Context.insert(InstX8632Test::create(Func, Src0, Src1));
552 }
553 void _ucomiss(Operand *Src0, Operand *Src1) {
554 Context.insert(InstX8632Ucomiss::create(Func, Src0, Src1));
555 }
556 void _ud2() { Context.insert(InstX8632UD2::create(Func)); }
557 void _xadd(Operand *Dest, Variable *Src, bool Locked) {
558 Context.insert(InstX8632Xadd::create(Func, Dest, Src, Locked));
559 // The xadd exchanges Dest and Src (modifying Src).
560 // Model that update with a FakeDef followed by a FakeUse.
561 Context.insert(
562 InstFakeDef::create(Func, Src, llvm::dyn_cast<Variable>(Dest)));
563 _set_dest_nonkillable();
564 Context.insert(InstFakeUse::create(Func, Src));
565 }
566 void _xchg(Operand *Dest, Variable *Src) {
567 Context.insert(InstX8632Xchg::create(Func, Dest, Src));
568 // The xchg modifies Dest and Src -- model that update with a
569 // FakeDef/FakeUse.
570 Context.insert(
571 InstFakeDef::create(Func, Src, llvm::dyn_cast<Variable>(Dest)));
572 _set_dest_nonkillable();
573 Context.insert(InstFakeUse::create(Func, Src));
574 }
575 void _xor(Variable *Dest, Operand *Src0) {
576 Context.insert(InstX8632Xor::create(Func, Dest, Src0));
577 }
578 void _xor_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) {
579 Context.insert(InstX8632XorRMW::create(Func, DestSrc0, Src1));
580 }
581 void _set_dest_nonkillable() {
582 Context.getLastInserted()->setDestNonKillable();
583 }
584
585 bool optimizeScalarMul(Variable *Dest, Operand *Src0, int32_t Src1);
586 void findRMW();
587
588 X86InstructionSet InstructionSet = X86InstructionSet::Begin;
589 bool IsEbpBasedFrame = false;
590 bool NeedsStackAlignment = false;
591 size_t SpillAreaSizeBytes = 0;
592 llvm::SmallBitVector TypeToRegisterSet[IceType_NUM];
593 llvm::SmallBitVector ScratchRegs;
594 llvm::SmallBitVector RegsUsed;
595 VarList PhysicalRegisters[IceType_NUM];
596 static IceString RegNames[];
597
598 // Randomize a given immediate operand
599 Operand *randomizeOrPoolImmediate(Constant *Immediate,
600 int32_t RegNum = Variable::NoRegister);
601 OperandX8632Mem *
602 randomizeOrPoolImmediate(OperandX8632Mem *MemOperand,
603 int32_t RegNum = Variable::NoRegister);
604 bool RandomizationPoolingPaused = false;
605
606 private:
607 ~TargetX8632() override {}
608 BoolFolding FoldingInfo;
609 }; 50 };
610 51
611 class TargetDataX8632 final : public TargetDataLowering { 52 class TargetDataX8632 final : public TargetDataLowering {
612 TargetDataX8632() = delete; 53 TargetDataX8632() = delete;
613 TargetDataX8632(const TargetDataX8632 &) = delete; 54 TargetDataX8632(const TargetDataX8632 &) = delete;
614 TargetDataX8632 &operator=(const TargetDataX8632 &) = delete; 55 TargetDataX8632 &operator=(const TargetDataX8632 &) = delete;
615 56
616 public: 57 public:
617 static std::unique_ptr<TargetDataLowering> create(GlobalContext *Ctx) { 58 static std::unique_ptr<TargetDataLowering> create(GlobalContext *Ctx) {
618 return std::unique_ptr<TargetDataLowering>(new TargetDataX8632(Ctx)); 59 return std::unique_ptr<TargetDataLowering>(new TargetDataX8632(Ctx));
619 } 60 }
620 61
621 void lowerGlobals(const VariableDeclarationList &Vars, 62 void lowerGlobals(const VariableDeclarationList &Vars,
622 const IceString &SectionSuffix) override; 63 const IceString &SectionSuffix) override;
623 void lowerConstants() override; 64 void lowerConstants() override;
624 65
625 protected: 66 protected:
626 explicit TargetDataX8632(GlobalContext *Ctx); 67 explicit TargetDataX8632(GlobalContext *Ctx);
627 68
628 private: 69 private:
629 ~TargetDataX8632() override {} 70 ~TargetDataX8632() override = default;
630 template <typename T> static void emitConstantPool(GlobalContext *Ctx); 71 template <typename T> static void emitConstantPool(GlobalContext *Ctx);
631 }; 72 };
632 73
633 class TargetHeaderX8632 final : public TargetHeaderLowering { 74 class TargetHeaderX8632 final : public TargetHeaderLowering {
634 TargetHeaderX8632() = delete; 75 TargetHeaderX8632() = delete;
635 TargetHeaderX8632(const TargetHeaderX8632 &) = delete; 76 TargetHeaderX8632(const TargetHeaderX8632 &) = delete;
636 TargetHeaderX8632 &operator=(const TargetHeaderX8632 &) = delete; 77 TargetHeaderX8632 &operator=(const TargetHeaderX8632 &) = delete;
637 78
638 public: 79 public:
639 static std::unique_ptr<TargetHeaderLowering> create(GlobalContext *Ctx) { 80 static std::unique_ptr<TargetHeaderLowering> create(GlobalContext *Ctx) {
640 return std::unique_ptr<TargetHeaderLowering>(new TargetHeaderX8632(Ctx)); 81 return std::unique_ptr<TargetHeaderLowering>(new TargetHeaderX8632(Ctx));
641 } 82 }
642 83
643 protected: 84 protected:
644 explicit TargetHeaderX8632(GlobalContext *Ctx); 85 explicit TargetHeaderX8632(GlobalContext *Ctx);
645 86
646 private: 87 private:
647 ~TargetHeaderX8632() = default; 88 ~TargetHeaderX8632() = default;
648 }; 89 };
649 90
650 } // end of namespace Ice 91 } // end of namespace Ice
651 92
652 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8632_H 93 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8632_H
OLDNEW
« no previous file with comments | « src/IceInst.h ('k') | src/IceTargetLoweringX8632.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698