blob: a7c4275afd1f5f82f6009cab2ec7084205ca96df [file] [log] [blame]
John Porto7e93c622015-06-23 10:58:57 -07001//===- subzero/src/IceTargetLoweringX86Base.h - x86 lowering ----*- C++ -*-===//
2//
3// The Subzero Code Generator
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file declares the TargetLoweringX86 template class, which
11// implements the TargetLowering base interface for the x86
12// architecture.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef SUBZERO_SRC_ICETARGETLOWERINGX86BASE_H
17#define SUBZERO_SRC_ICETARGETLOWERINGX86BASE_H
18
19#include <unordered_map>
20
21#include "IceDefs.h"
22#include "IceInst.h"
23#include "IceTargetLowering.h"
24
25namespace Ice {
26namespace X86Internal {
27
28template <class MachineTraits> class BoolFolding;
29
30template <class Machine> struct MachineTraits {};
31
32template <class Machine> class TargetX86Base : public Machine {
33 TargetX86Base() = delete;
34 TargetX86Base(const TargetX86Base &) = delete;
35 TargetX86Base &operator=(const TargetX86Base &) = delete;
36
37protected:
38 using TargetLowering::H_bitcast_16xi1_i16;
39 using TargetLowering::H_bitcast_8xi1_i8;
40 using TargetLowering::H_bitcast_i16_16xi1;
41 using TargetLowering::H_bitcast_i8_8xi1;
42 using TargetLowering::H_call_ctpop_i32;
43 using TargetLowering::H_call_ctpop_i64;
44 using TargetLowering::H_call_longjmp;
45 using TargetLowering::H_call_memcpy;
46 using TargetLowering::H_call_memmove;
47 using TargetLowering::H_call_memset;
48 using TargetLowering::H_call_read_tp;
49 using TargetLowering::H_call_setjmp;
50 using TargetLowering::H_fptosi_f32_i64;
51 using TargetLowering::H_fptosi_f64_i64;
52 using TargetLowering::H_fptoui_4xi32_f32;
53 using TargetLowering::H_fptoui_f32_i32;
54 using TargetLowering::H_fptoui_f32_i64;
55 using TargetLowering::H_fptoui_f64_i32;
56 using TargetLowering::H_fptoui_f64_i64;
57 using TargetLowering::H_frem_f32;
58 using TargetLowering::H_frem_f64;
59 using TargetLowering::H_sdiv_i64;
60 using TargetLowering::H_sitofp_i64_f32;
61 using TargetLowering::H_sitofp_i64_f64;
62 using TargetLowering::H_srem_i64;
63 using TargetLowering::H_udiv_i64;
64 using TargetLowering::H_uitofp_4xi32_4xf32;
65 using TargetLowering::H_uitofp_i32_f32;
66 using TargetLowering::H_uitofp_i32_f64;
67 using TargetLowering::H_uitofp_i64_f32;
68 using TargetLowering::H_uitofp_i64_f64;
69 using TargetLowering::H_urem_i64;
70
71 using TargetLowering::alignStackSpillAreas;
72 using TargetLowering::assignVarStackSlots;
73 using TargetLowering::inferTwoAddress;
74 using TargetLowering::makeHelperCall;
75 using TargetLowering::getVarStackSlotParams;
76
77public:
78 using Traits = MachineTraits<Machine>;
79 using BoolFolding = ::Ice::X86Internal::BoolFolding<Traits>;
80
81 using TargetLowering::RegSet_All;
82 using TargetLowering::RegSet_CalleeSave;
83 using TargetLowering::RegSet_CallerSave;
84 using TargetLowering::RegSet_FramePointer;
85 using TargetLowering::RegSet_None;
86 using TargetLowering::RegSet_StackPointer;
87 using TargetLowering::Context;
88 using TargetLowering::Ctx;
89 using TargetLowering::Func;
90 using TargetLowering::RegSetMask;
91
92 using TargetLowering::_bundle_lock;
93 using TargetLowering::_bundle_unlock;
94 using TargetLowering::getContext;
95 using TargetLowering::getStackAdjustment;
96 using TargetLowering::regAlloc;
97 using TargetLowering::resetStackAdjustment;
98
99 static TargetX86Base *create(Cfg *Func) { return new TargetX86Base(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 final;
148
149 typename Traits::InstructionSet getInstructionSet() const final {
150 return InstructionSet;
151 }
152
153protected:
154 explicit TargetX86Base(Cfg *Func);
155
156 void postLower() override;
157
158 void lowerAlloca(const InstAlloca *Inst) override;
159 void lowerArithmetic(const InstArithmetic *Inst) override;
160 void lowerAssign(const InstAssign *Inst) override;
161 void lowerBr(const InstBr *Inst) override;
162 void lowerCall(const InstCall *Inst) override;
163 void lowerCast(const InstCast *Inst) override;
164 void lowerExtractElement(const InstExtractElement *Inst) override;
165 void lowerFcmp(const InstFcmp *Inst) override;
166 void lowerIcmp(const InstIcmp *Inst) override;
167 void lowerIntrinsicCall(const InstIntrinsicCall *Inst) override;
168 void lowerInsertElement(const InstInsertElement *Inst) override;
169 void lowerLoad(const InstLoad *Inst) override;
170 void lowerPhi(const InstPhi *Inst) override;
171 void lowerRet(const InstRet *Inst) override;
172 void lowerSelect(const InstSelect *Inst) override;
173 void lowerStore(const InstStore *Inst) override;
174 void lowerSwitch(const InstSwitch *Inst) override;
175 void lowerUnreachable(const InstUnreachable *Inst) override;
176 void lowerOther(const Inst *Instr) override;
177 void lowerRMW(const InstX8632FakeRMW *RMW);
178 void prelowerPhis() override;
179 void lowerPhiAssignments(CfgNode *Node,
180 const AssignList &Assignments) override;
181 void doAddressOptLoad() override;
182 void doAddressOptStore() override;
183 void randomlyInsertNop(float Probability) override;
184
185 // Naive lowering of cmpxchg.
186 void lowerAtomicCmpxchg(Variable *DestPrev, Operand *Ptr, Operand *Expected,
187 Operand *Desired);
188 // Attempt a more optimized lowering of cmpxchg. Returns true if optimized.
189 bool tryOptimizedCmpxchgCmpBr(Variable *DestPrev, Operand *Ptr,
190 Operand *Expected, Operand *Desired);
191 void lowerAtomicRMW(Variable *Dest, uint32_t Operation, Operand *Ptr,
192 Operand *Val);
193 void lowerCountZeros(bool Cttz, Type Ty, Variable *Dest, Operand *FirstVal,
194 Operand *SecondVal);
195
196 typedef void (TargetX86Base::*LowerBinOp)(Variable *, Operand *);
197 void expandAtomicRMWAsCmpxchg(LowerBinOp op_lo, LowerBinOp op_hi,
198 Variable *Dest, Operand *Ptr, Operand *Val);
199
200 void eliminateNextVectorSextInstruction(Variable *SignExtendedResult);
201
202 void scalarizeArithmetic(InstArithmetic::OpKind K, Variable *Dest,
203 Operand *Src0, Operand *Src1);
204
205 // Operand legalization helpers. To deal with address mode
206 // constraints, the helpers will create a new Operand and emit
207 // instructions that guarantee that the Operand kind is one of those
208 // indicated by the LegalMask (a bitmask of allowed kinds). If the
209 // input Operand is known to already meet the constraints, it may be
210 // simply returned as the result, without creating any new
211 // instructions or operands.
212 enum OperandLegalization {
213 Legal_None = 0,
214 Legal_Reg = 1 << 0, // physical register, not stack location
215 Legal_Imm = 1 << 1,
216 Legal_Mem = 1 << 2, // includes [eax+4*ecx] as well as [esp+12]
217 Legal_All = ~Legal_None
218 };
219 typedef uint32_t LegalMask;
220 Operand *legalize(Operand *From, LegalMask Allowed = Legal_All,
221 int32_t RegNum = Variable::NoRegister);
222 Variable *legalizeToVar(Operand *From, int32_t RegNum = Variable::NoRegister);
223 // Legalize the first source operand for use in the cmp instruction.
224 Operand *legalizeSrc0ForCmp(Operand *Src0, Operand *Src1);
225 // Turn a pointer operand into a memory operand that can be
226 // used by a real load/store operation. Legalizes the operand as well.
227 // This is a nop if the operand is already a legal memory operand.
228 OperandX8632Mem *formMemoryOperand(Operand *Ptr, Type Ty,
229 bool DoLegalize = true);
230
231 Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister);
232 static Type stackSlotType();
233
234 Variable *copyToReg(Operand *Src, int32_t RegNum = Variable::NoRegister);
235
236 // Returns a vector in a register with the given constant entries.
237 Variable *makeVectorOfZeros(Type Ty, int32_t RegNum = Variable::NoRegister);
238 Variable *makeVectorOfOnes(Type Ty, int32_t RegNum = Variable::NoRegister);
239 Variable *makeVectorOfMinusOnes(Type Ty,
240 int32_t RegNum = Variable::NoRegister);
241 Variable *makeVectorOfHighOrderBits(Type Ty,
242 int32_t RegNum = Variable::NoRegister);
243 Variable *makeVectorOfFabsMask(Type Ty,
244 int32_t RegNum = Variable::NoRegister);
245
246 // Return a memory operand corresponding to a stack allocated Variable.
247 OperandX8632Mem *getMemoryOperandForStackSlot(Type Ty, Variable *Slot,
248 uint32_t Offset = 0);
249
250 void makeRandomRegisterPermutation(
251 llvm::SmallVectorImpl<int32_t> &Permutation,
252 const llvm::SmallBitVector &ExcludeRegisters) const override;
253
254 // The following are helpers that insert lowered x86 instructions
255 // with minimal syntactic overhead, so that the lowering code can
256 // look as close to assembly as practical.
257 void _adc(Variable *Dest, Operand *Src0) {
258 Context.insert(InstX8632Adc::create(Func, Dest, Src0));
259 }
260 void _adc_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) {
261 Context.insert(InstX8632AdcRMW::create(Func, DestSrc0, Src1));
262 }
263 void _add(Variable *Dest, Operand *Src0) {
264 Context.insert(InstX8632Add::create(Func, Dest, Src0));
265 }
266 void _add_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) {
267 Context.insert(InstX8632AddRMW::create(Func, DestSrc0, Src1));
268 }
269 void _adjust_stack(int32_t Amount) {
270 Context.insert(InstX8632AdjustStack::create(
271 Func, Amount, getPhysicalRegister(RegX8632::Reg_esp)));
272 }
273 void _addps(Variable *Dest, Operand *Src0) {
274 Context.insert(InstX8632Addps::create(Func, Dest, Src0));
275 }
276 void _addss(Variable *Dest, Operand *Src0) {
277 Context.insert(InstX8632Addss::create(Func, Dest, Src0));
278 }
279 void _and(Variable *Dest, Operand *Src0) {
280 Context.insert(InstX8632And::create(Func, Dest, Src0));
281 }
282 void _and_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) {
283 Context.insert(InstX8632AndRMW::create(Func, DestSrc0, Src1));
284 }
285 void _blendvps(Variable *Dest, Operand *Src0, Operand *Src1) {
286 Context.insert(InstX8632Blendvps::create(Func, Dest, Src0, Src1));
287 }
288 void _br(CondX86::BrCond Condition, CfgNode *TargetTrue,
289 CfgNode *TargetFalse) {
290 Context.insert(
291 InstX8632Br::create(Func, TargetTrue, TargetFalse, Condition));
292 }
293 void _br(CfgNode *Target) {
294 Context.insert(InstX8632Br::create(Func, Target));
295 }
296 void _br(CondX86::BrCond Condition, CfgNode *Target) {
297 Context.insert(InstX8632Br::create(Func, Target, Condition));
298 }
299 void _br(CondX86::BrCond Condition, InstX8632Label *Label) {
300 Context.insert(InstX8632Br::create(Func, Label, Condition));
301 }
302 void _bsf(Variable *Dest, Operand *Src0) {
303 Context.insert(InstX8632Bsf::create(Func, Dest, Src0));
304 }
305 void _bsr(Variable *Dest, Operand *Src0) {
306 Context.insert(InstX8632Bsr::create(Func, Dest, Src0));
307 }
308 void _bswap(Variable *SrcDest) {
309 Context.insert(InstX8632Bswap::create(Func, SrcDest));
310 }
311 void _cbwdq(Variable *Dest, Operand *Src0) {
312 Context.insert(InstX8632Cbwdq::create(Func, Dest, Src0));
313 }
314 void _cmov(Variable *Dest, Operand *Src0, CondX86::BrCond Condition) {
315 Context.insert(InstX8632Cmov::create(Func, Dest, Src0, Condition));
316 }
317 void _cmp(Operand *Src0, Operand *Src1) {
318 Context.insert(InstX8632Icmp::create(Func, Src0, Src1));
319 }
320 void _cmpps(Variable *Dest, Operand *Src0, CondX86::CmppsCond Condition) {
321 Context.insert(InstX8632Cmpps::create(Func, Dest, Src0, Condition));
322 }
323 void _cmpxchg(Operand *DestOrAddr, Variable *Eax, Variable *Desired,
324 bool Locked) {
325 Context.insert(
326 InstX8632Cmpxchg::create(Func, DestOrAddr, Eax, Desired, Locked));
327 // Mark eax as possibly modified by cmpxchg.
328 Context.insert(
329 InstFakeDef::create(Func, Eax, llvm::dyn_cast<Variable>(DestOrAddr)));
330 _set_dest_nonkillable();
331 Context.insert(InstFakeUse::create(Func, Eax));
332 }
333 void _cmpxchg8b(OperandX8632Mem *Addr, Variable *Edx, Variable *Eax,
334 Variable *Ecx, Variable *Ebx, bool Locked) {
335 Context.insert(
336 InstX8632Cmpxchg8b::create(Func, Addr, Edx, Eax, Ecx, Ebx, Locked));
337 // Mark edx, and eax as possibly modified by cmpxchg8b.
338 Context.insert(InstFakeDef::create(Func, Edx));
339 _set_dest_nonkillable();
340 Context.insert(InstFakeUse::create(Func, Edx));
341 Context.insert(InstFakeDef::create(Func, Eax));
342 _set_dest_nonkillable();
343 Context.insert(InstFakeUse::create(Func, Eax));
344 }
345 void _cvt(Variable *Dest, Operand *Src0, InstX8632Cvt::CvtVariant Variant) {
346 Context.insert(InstX8632Cvt::create(Func, Dest, Src0, Variant));
347 }
348 void _div(Variable *Dest, Operand *Src0, Operand *Src1) {
349 Context.insert(InstX8632Div::create(Func, Dest, Src0, Src1));
350 }
351 void _divps(Variable *Dest, Operand *Src0) {
352 Context.insert(InstX8632Divps::create(Func, Dest, Src0));
353 }
354 void _divss(Variable *Dest, Operand *Src0) {
355 Context.insert(InstX8632Divss::create(Func, Dest, Src0));
356 }
357 void _fld(Operand *Src0) { Context.insert(InstX8632Fld::create(Func, Src0)); }
358 void _fstp(Variable *Dest) {
359 Context.insert(InstX8632Fstp::create(Func, Dest));
360 }
361 void _idiv(Variable *Dest, Operand *Src0, Operand *Src1) {
362 Context.insert(InstX8632Idiv::create(Func, Dest, Src0, Src1));
363 }
364 void _imul(Variable *Dest, Operand *Src0) {
365 Context.insert(InstX8632Imul::create(Func, Dest, Src0));
366 }
367 void _insertps(Variable *Dest, Operand *Src0, Operand *Src1) {
368 Context.insert(InstX8632Insertps::create(Func, Dest, Src0, Src1));
369 }
370 void _jmp(Operand *Target) {
371 Context.insert(InstX8632Jmp::create(Func, Target));
372 }
373 void _lea(Variable *Dest, Operand *Src0) {
374 Context.insert(InstX8632Lea::create(Func, Dest, Src0));
375 }
376 void _mfence() { Context.insert(InstX8632Mfence::create(Func)); }
377 // If Dest=nullptr is passed in, then a new variable is created,
378 // marked as infinite register allocation weight, and returned
379 // through the in/out Dest argument.
380 void _mov(Variable *&Dest, Operand *Src0,
381 int32_t RegNum = Variable::NoRegister) {
382 if (Dest == nullptr)
383 Dest = makeReg(Src0->getType(), RegNum);
384 Context.insert(InstX8632Mov::create(Func, Dest, Src0));
385 }
386 void _mov_nonkillable(Variable *Dest, Operand *Src0) {
387 Inst *NewInst = InstX8632Mov::create(Func, Dest, Src0);
388 NewInst->setDestNonKillable();
389 Context.insert(NewInst);
390 }
391 void _movd(Variable *Dest, Operand *Src0) {
392 Context.insert(InstX8632Movd::create(Func, Dest, Src0));
393 }
394 void _movp(Variable *Dest, Operand *Src0) {
395 Context.insert(InstX8632Movp::create(Func, Dest, Src0));
396 }
397 void _movq(Variable *Dest, Operand *Src0) {
398 Context.insert(InstX8632Movq::create(Func, Dest, Src0));
399 }
400 void _movss(Variable *Dest, Variable *Src0) {
401 Context.insert(InstX8632MovssRegs::create(Func, Dest, Src0));
402 }
403 void _movsx(Variable *Dest, Operand *Src0) {
404 Context.insert(InstX8632Movsx::create(Func, Dest, Src0));
405 }
406 void _movzx(Variable *Dest, Operand *Src0) {
407 Context.insert(InstX8632Movzx::create(Func, Dest, Src0));
408 }
409 void _mul(Variable *Dest, Variable *Src0, Operand *Src1) {
410 Context.insert(InstX8632Mul::create(Func, Dest, Src0, Src1));
411 }
412 void _mulps(Variable *Dest, Operand *Src0) {
413 Context.insert(InstX8632Mulps::create(Func, Dest, Src0));
414 }
415 void _mulss(Variable *Dest, Operand *Src0) {
416 Context.insert(InstX8632Mulss::create(Func, Dest, Src0));
417 }
418 void _neg(Variable *SrcDest) {
419 Context.insert(InstX8632Neg::create(Func, SrcDest));
420 }
421 void _nop(SizeT Variant) {
422 Context.insert(InstX8632Nop::create(Func, Variant));
423 }
424 void _or(Variable *Dest, Operand *Src0) {
425 Context.insert(InstX8632Or::create(Func, Dest, Src0));
426 }
427 void _or_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) {
428 Context.insert(InstX8632OrRMW::create(Func, DestSrc0, Src1));
429 }
430 void _padd(Variable *Dest, Operand *Src0) {
431 Context.insert(InstX8632Padd::create(Func, Dest, Src0));
432 }
433 void _pand(Variable *Dest, Operand *Src0) {
434 Context.insert(InstX8632Pand::create(Func, Dest, Src0));
435 }
436 void _pandn(Variable *Dest, Operand *Src0) {
437 Context.insert(InstX8632Pandn::create(Func, Dest, Src0));
438 }
439 void _pblendvb(Variable *Dest, Operand *Src0, Operand *Src1) {
440 Context.insert(InstX8632Pblendvb::create(Func, Dest, Src0, Src1));
441 }
442 void _pcmpeq(Variable *Dest, Operand *Src0) {
443 Context.insert(InstX8632Pcmpeq::create(Func, Dest, Src0));
444 }
445 void _pcmpgt(Variable *Dest, Operand *Src0) {
446 Context.insert(InstX8632Pcmpgt::create(Func, Dest, Src0));
447 }
448 void _pextr(Variable *Dest, Operand *Src0, Operand *Src1) {
449 Context.insert(InstX8632Pextr::create(Func, Dest, Src0, Src1));
450 }
451 void _pinsr(Variable *Dest, Operand *Src0, Operand *Src1) {
452 Context.insert(InstX8632Pinsr::create(Func, Dest, Src0, Src1));
453 }
454 void _pmull(Variable *Dest, Operand *Src0) {
455 Context.insert(InstX8632Pmull::create(Func, Dest, Src0));
456 }
457 void _pmuludq(Variable *Dest, Operand *Src0) {
458 Context.insert(InstX8632Pmuludq::create(Func, Dest, Src0));
459 }
460 void _pop(Variable *Dest) {
461 Context.insert(InstX8632Pop::create(Func, Dest));
462 }
463 void _por(Variable *Dest, Operand *Src0) {
464 Context.insert(InstX8632Por::create(Func, Dest, Src0));
465 }
466 void _pshufd(Variable *Dest, Operand *Src0, Operand *Src1) {
467 Context.insert(InstX8632Pshufd::create(Func, Dest, Src0, Src1));
468 }
469 void _psll(Variable *Dest, Operand *Src0) {
470 Context.insert(InstX8632Psll::create(Func, Dest, Src0));
471 }
472 void _psra(Variable *Dest, Operand *Src0) {
473 Context.insert(InstX8632Psra::create(Func, Dest, Src0));
474 }
475 void _psrl(Variable *Dest, Operand *Src0) {
476 Context.insert(InstX8632Psrl::create(Func, Dest, Src0));
477 }
478 void _psub(Variable *Dest, Operand *Src0) {
479 Context.insert(InstX8632Psub::create(Func, Dest, Src0));
480 }
481 void _push(Variable *Src0) {
482 Context.insert(InstX8632Push::create(Func, Src0));
483 }
484 void _pxor(Variable *Dest, Operand *Src0) {
485 Context.insert(InstX8632Pxor::create(Func, Dest, Src0));
486 }
487 void _ret(Variable *Src0 = nullptr) {
488 Context.insert(InstX8632Ret::create(Func, Src0));
489 }
490 void _rol(Variable *Dest, Operand *Src0) {
491 Context.insert(InstX8632Rol::create(Func, Dest, Src0));
492 }
493 void _sar(Variable *Dest, Operand *Src0) {
494 Context.insert(InstX8632Sar::create(Func, Dest, Src0));
495 }
496 void _sbb(Variable *Dest, Operand *Src0) {
497 Context.insert(InstX8632Sbb::create(Func, Dest, Src0));
498 }
499 void _sbb_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) {
500 Context.insert(InstX8632SbbRMW::create(Func, DestSrc0, Src1));
501 }
502 void _setcc(Variable *Dest, CondX86::BrCond Condition) {
503 Context.insert(InstX8632Setcc::create(Func, Dest, Condition));
504 }
505 void _shl(Variable *Dest, Operand *Src0) {
506 Context.insert(InstX8632Shl::create(Func, Dest, Src0));
507 }
508 void _shld(Variable *Dest, Variable *Src0, Variable *Src1) {
509 Context.insert(InstX8632Shld::create(Func, Dest, Src0, Src1));
510 }
511 void _shr(Variable *Dest, Operand *Src0) {
512 Context.insert(InstX8632Shr::create(Func, Dest, Src0));
513 }
514 void _shrd(Variable *Dest, Variable *Src0, Variable *Src1) {
515 Context.insert(InstX8632Shrd::create(Func, Dest, Src0, Src1));
516 }
517 void _shufps(Variable *Dest, Operand *Src0, Operand *Src1) {
518 Context.insert(InstX8632Shufps::create(Func, Dest, Src0, Src1));
519 }
520 void _sqrtss(Variable *Dest, Operand *Src0) {
521 Context.insert(InstX8632Sqrtss::create(Func, Dest, Src0));
522 }
523 void _store(Operand *Value, OperandX8632 *Mem) {
524 Context.insert(InstX8632Store::create(Func, Value, Mem));
525 }
526 void _storep(Variable *Value, OperandX8632Mem *Mem) {
527 Context.insert(InstX8632StoreP::create(Func, Value, Mem));
528 }
529 void _storeq(Variable *Value, OperandX8632Mem *Mem) {
530 Context.insert(InstX8632StoreQ::create(Func, Value, Mem));
531 }
532 void _sub(Variable *Dest, Operand *Src0) {
533 Context.insert(InstX8632Sub::create(Func, Dest, Src0));
534 }
535 void _sub_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) {
536 Context.insert(InstX8632SubRMW::create(Func, DestSrc0, Src1));
537 }
538 void _subps(Variable *Dest, Operand *Src0) {
539 Context.insert(InstX8632Subps::create(Func, Dest, Src0));
540 }
541 void _subss(Variable *Dest, Operand *Src0) {
542 Context.insert(InstX8632Subss::create(Func, Dest, Src0));
543 }
544 void _test(Operand *Src0, Operand *Src1) {
545 Context.insert(InstX8632Test::create(Func, Src0, Src1));
546 }
547 void _ucomiss(Operand *Src0, Operand *Src1) {
548 Context.insert(InstX8632Ucomiss::create(Func, Src0, Src1));
549 }
550 void _ud2() { Context.insert(InstX8632UD2::create(Func)); }
551 void _xadd(Operand *Dest, Variable *Src, bool Locked) {
552 Context.insert(InstX8632Xadd::create(Func, Dest, Src, Locked));
553 // The xadd exchanges Dest and Src (modifying Src).
554 // Model that update with a FakeDef followed by a FakeUse.
555 Context.insert(
556 InstFakeDef::create(Func, Src, llvm::dyn_cast<Variable>(Dest)));
557 _set_dest_nonkillable();
558 Context.insert(InstFakeUse::create(Func, Src));
559 }
560 void _xchg(Operand *Dest, Variable *Src) {
561 Context.insert(InstX8632Xchg::create(Func, Dest, Src));
562 // The xchg modifies Dest and Src -- model that update with a
563 // FakeDef/FakeUse.
564 Context.insert(
565 InstFakeDef::create(Func, Src, llvm::dyn_cast<Variable>(Dest)));
566 _set_dest_nonkillable();
567 Context.insert(InstFakeUse::create(Func, Src));
568 }
569 void _xor(Variable *Dest, Operand *Src0) {
570 Context.insert(InstX8632Xor::create(Func, Dest, Src0));
571 }
572 void _xor_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) {
573 Context.insert(InstX8632XorRMW::create(Func, DestSrc0, Src1));
574 }
575 void _set_dest_nonkillable() {
576 Context.getLastInserted()->setDestNonKillable();
577 }
578
579 bool optimizeScalarMul(Variable *Dest, Operand *Src0, int32_t Src1);
580 void findRMW();
581
582 typename Traits::InstructionSet InstructionSet =
583 Traits::InstructionSet::Begin;
584 bool IsEbpBasedFrame = false;
585 bool NeedsStackAlignment = false;
586 size_t SpillAreaSizeBytes = 0;
587 llvm::SmallBitVector TypeToRegisterSet[IceType_NUM];
588 llvm::SmallBitVector ScratchRegs;
589 llvm::SmallBitVector RegsUsed;
590 VarList PhysicalRegisters[IceType_NUM];
591 static IceString RegNames[];
592
593 // Randomize a given immediate operand
594 Operand *randomizeOrPoolImmediate(Constant *Immediate,
595 int32_t RegNum = Variable::NoRegister);
596 OperandX8632Mem *
597 randomizeOrPoolImmediate(OperandX8632Mem *MemOperand,
598 int32_t RegNum = Variable::NoRegister);
599 bool RandomizationPoolingPaused = false;
600
601private:
602 ~TargetX86Base() override {}
603 BoolFolding FoldingInfo;
604};
605} // end of namespace X86Internal
606} // end of namespace Ice
607
608#include "IceTargetLoweringX86BaseImpl.h"
609
610#endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASE_H