blob: 6d209dc8f4c72d179953ef8d9a0c83adea4b9cce [file] [log] [blame]
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001//===- subzero/src/IceTargetLoweringX8632.h - x86-32 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 TargetLoweringX8632 class, which
11// implements the TargetLowering interface for the x86-32
12// architecture.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef SUBZERO_SRC_ICETARGETLOWERINGX8632_H
17#define SUBZERO_SRC_ICETARGETLOWERINGX8632_H
18
19#include "IceDefs.h"
20#include "IceTargetLowering.h"
21#include "IceInstX8632.h"
22
23namespace Ice {
24
25class TargetX8632 : public TargetLowering {
26public:
27 static TargetX8632 *create(Cfg *Func) { return new TargetX8632(Func); }
28
29 virtual void translateOm1();
Jim Stichnothd97c7df2014-06-04 11:57:08 -070030 virtual void translateO2();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070031
32 virtual Variable *getPhysicalRegister(SizeT RegNum);
33 virtual IceString getRegName(SizeT RegNum, Type Ty) const;
34 virtual llvm::SmallBitVector getRegisterSet(RegSetMask Include,
35 RegSetMask Exclude) const;
36 virtual const llvm::SmallBitVector &getRegisterSetForType(Type Ty) const {
37 return TypeToRegisterSet[Ty];
38 }
39 virtual bool hasFramePointer() const { return IsEbpBasedFrame; }
40 virtual SizeT getFrameOrStackReg() const {
41 return IsEbpBasedFrame ? Reg_ebp : Reg_esp;
42 }
43 virtual size_t typeWidthInBytesOnStack(Type Ty) {
44 // Round up to the next multiple of 4 bytes. In particular, i1,
45 // i8, and i16 are rounded up to 4 bytes.
46 return (typeWidthInBytes(Ty) + 3) & ~3;
47 }
48 virtual void emitVariable(const Variable *Var, const Cfg *Func) const;
Matt Wala45a06232014-07-09 16:33:22 -070049 virtual void lowerArguments();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070050 virtual void addProlog(CfgNode *Node);
51 virtual void addEpilog(CfgNode *Node);
Jim Stichnothf61d5b22014-05-23 13:31:24 -070052 virtual void emitConstants() const;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070053 SizeT makeNextLabelNumber() { return NextLabelNumber++; }
54 // Ensure that a 64-bit Variable has been split into 2 32-bit
55 // Variables, creating them if necessary. This is needed for all
56 // I64 operations, and it is needed for pushing F64 arguments for
57 // function calls using the 32-bit push instruction (though the
58 // latter could be done by directly writing to the stack).
59 void split64(Variable *Var);
Matt Wala45a06232014-07-09 16:33:22 -070060 void finishArgumentLowering(Variable *Arg, Variable *FramePtr,
61 size_t BasicFrameOffset, size_t &InArgsSizeBytes);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070062 Operand *loOperand(Operand *Operand);
63 Operand *hiOperand(Operand *Operand);
64
65 enum Registers {
66#define X(val, init, name, name16, name8, scratch, preserved, stackptr, \
67 frameptr, isI8, isInt, isFP) \
68 val init,
69 REGX8632_TABLE
70#undef X
71 Reg_NUM
72 };
73
Matt Wala0a450512014-07-30 12:44:39 -070074 enum X86InstructionSet {
75 // SSE2 is the PNaCl baseline instruction set.
76 SSE2,
77 SSE4_1
78 };
79
80 X86InstructionSet getInstructionSet() const { return InstructionSet; }
81
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070082protected:
83 TargetX8632(Cfg *Func);
84
85 virtual void postLower();
86
87 virtual void lowerAlloca(const InstAlloca *Inst);
88 virtual void lowerArithmetic(const InstArithmetic *Inst);
89 virtual void lowerAssign(const InstAssign *Inst);
90 virtual void lowerBr(const InstBr *Inst);
91 virtual void lowerCall(const InstCall *Inst);
92 virtual void lowerCast(const InstCast *Inst);
Matt Wala49889232014-07-18 12:45:09 -070093 virtual void lowerExtractElement(const InstExtractElement *Inst);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070094 virtual void lowerFcmp(const InstFcmp *Inst);
95 virtual void lowerIcmp(const InstIcmp *Inst);
Jan Voung3bd9f1a2014-06-18 10:50:57 -070096 virtual void lowerIntrinsicCall(const InstIntrinsicCall *Inst);
Matt Wala49889232014-07-18 12:45:09 -070097 virtual void lowerInsertElement(const InstInsertElement *Inst);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070098 virtual void lowerLoad(const InstLoad *Inst);
99 virtual void lowerPhi(const InstPhi *Inst);
100 virtual void lowerRet(const InstRet *Inst);
101 virtual void lowerSelect(const InstSelect *Inst);
102 virtual void lowerStore(const InstStore *Inst);
103 virtual void lowerSwitch(const InstSwitch *Inst);
104 virtual void lowerUnreachable(const InstUnreachable *Inst);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700105 virtual void doAddressOptLoad();
106 virtual void doAddressOptStore();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700107
Jan Voungc820ddf2014-07-29 14:38:51 -0700108 // Naive lowering of cmpxchg.
Jan Vounga3a01a22014-07-14 10:32:41 -0700109 void lowerAtomicCmpxchg(Variable *DestPrev, Operand *Ptr, Operand *Expected,
110 Operand *Desired);
Jan Voungc820ddf2014-07-29 14:38:51 -0700111 // Attempt a more optimized lowering of cmpxchg. Returns true if optimized.
112 bool tryOptimizedCmpxchgCmpBr(Variable *DestPrev, Operand *Ptr,
113 Operand *Expected, Operand *Desired);
Jan Voung5cd240d2014-06-25 10:36:46 -0700114 void lowerAtomicRMW(Variable *Dest, uint32_t Operation, Operand *Ptr,
115 Operand *Val);
Jan Vounge4da26f2014-07-15 17:52:39 -0700116 void lowerCountZeros(bool Cttz, Type Ty, Variable *Dest, Operand *FirstVal,
117 Operand *SecondVal);
Jan Voung5cd240d2014-06-25 10:36:46 -0700118
Jan Vounga3a01a22014-07-14 10:32:41 -0700119 typedef void (TargetX8632::*LowerBinOp)(Variable *, Operand *);
120 void expandAtomicRMWAsCmpxchg(LowerBinOp op_lo, LowerBinOp op_hi,
121 Variable *Dest, Operand *Ptr, Operand *Val);
122
Matt Walace0ca8f2014-07-24 12:34:20 -0700123 void eliminateNextVectorSextInstruction(Variable *SignExtendedResult);
124
Matt Walaafeaee42014-08-07 13:47:30 -0700125 void scalarizeArithmetic(InstArithmetic::OpKind K, Variable *Dest,
126 Operand *Src0, Operand *Src1);
127
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700128 // Operand legalization helpers. To deal with address mode
129 // constraints, the helpers will create a new Operand and emit
130 // instructions that guarantee that the Operand kind is one of those
131 // indicated by the LegalMask (a bitmask of allowed kinds). If the
132 // input Operand is known to already meet the constraints, it may be
133 // simply returned as the result, without creating any new
134 // instructions or operands.
135 enum OperandLegalization {
136 Legal_None = 0,
137 Legal_Reg = 1 << 0, // physical register, not stack location
138 Legal_Imm = 1 << 1,
139 Legal_Mem = 1 << 2, // includes [eax+4*ecx] as well as [esp+12]
Jim Stichnothde4ca712014-06-29 08:13:48 -0700140 // TODO(stichnot): LEAHACK: remove Legal_Reloc once a proper
141 // emitter is used.
142 Legal_Reloc = 1 << 3,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700143 Legal_All = ~Legal_None
144 };
145 typedef uint32_t LegalMask;
Jim Stichnothde4ca712014-06-29 08:13:48 -0700146 Operand *legalize(Operand *From, LegalMask Allowed = Legal_All & ~Legal_Reloc,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700147 bool AllowOverlap = false,
148 int32_t RegNum = Variable::NoRegister);
149 Variable *legalizeToVar(Operand *From, bool AllowOverlap = false,
150 int32_t RegNum = Variable::NoRegister);
Jan Voung5cd240d2014-06-25 10:36:46 -0700151 // Turn a pointer operand into a memory operand that can be
152 // used by a real load/store operation. Legalizes the operand as well.
153 // This is a nop if the operand is already a legal memory operand.
154 OperandX8632Mem *FormMemoryOperand(Operand *Ptr, Type Ty);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700155
156 Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister);
157 InstCall *makeHelperCall(const IceString &Name, Variable *Dest,
158 SizeT MaxSrcs) {
159 bool SuppressMangling = true;
Matt Walaad8f7262014-07-14 17:37:37 -0700160 const Type FunctionPointerType = IceType_i32;
161 Constant *CallTarget =
162 Ctx->getConstantSym(FunctionPointerType, 0, Name, SuppressMangling);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700163 InstCall *Call = InstCall::create(Func, MaxSrcs, Dest, CallTarget);
164 return Call;
165 }
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700166 static Type stackSlotType();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700167
Matt Wala928f1292014-07-07 16:50:46 -0700168 Variable *copyToReg(Operand *Src, int32_t RegNum = Variable::NoRegister);
169
Matt Wala83b80362014-07-16 10:21:30 -0700170 // Returns a vector in a register with the given constant entries.
171 Variable *makeVectorOfZeros(Type Ty, int32_t RegNum = Variable::NoRegister);
172 Variable *makeVectorOfOnes(Type Ty, int32_t RegNum = Variable::NoRegister);
Matt Wala9a0168a2014-07-23 14:56:10 -0700173 Variable *makeVectorOfMinusOnes(Type Ty,
174 int32_t RegNum = Variable::NoRegister);
175 Variable *makeVectorOfHighOrderBits(Type Ty,
176 int32_t RegNum = Variable::NoRegister);
Matt Wala83b80362014-07-16 10:21:30 -0700177
Matt Wala49889232014-07-18 12:45:09 -0700178 // Return a memory operand corresponding to a stack allocated Variable.
179 OperandX8632Mem *getMemoryOperandForStackSlot(Type Ty, Variable *Slot,
180 uint32_t Offset = 0);
181
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700182 // The following are helpers that insert lowered x86 instructions
183 // with minimal syntactic overhead, so that the lowering code can
184 // look as close to assembly as practical.
185 void _adc(Variable *Dest, Operand *Src0) {
186 Context.insert(InstX8632Adc::create(Func, Dest, Src0));
187 }
188 void _add(Variable *Dest, Operand *Src0) {
189 Context.insert(InstX8632Add::create(Func, Dest, Src0));
190 }
Matt Wala105b7042014-08-11 19:56:19 -0700191 void _adjust_stack(int32_t Amount) {
192 Context.insert(InstX8632AdjustStack::create(Func, Amount));
193 }
Matt Wala8d1072e2014-07-11 15:43:51 -0700194 void _addps(Variable *Dest, Operand *Src0) {
195 Context.insert(InstX8632Addps::create(Func, Dest, Src0));
196 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700197 void _addss(Variable *Dest, Operand *Src0) {
198 Context.insert(InstX8632Addss::create(Func, Dest, Src0));
199 }
200 void _and(Variable *Dest, Operand *Src0) {
201 Context.insert(InstX8632And::create(Func, Dest, Src0));
202 }
Matt Wala0a450512014-07-30 12:44:39 -0700203 void _blendvps(Variable *Dest, Operand *Src0, Operand *Src1) {
204 Context.insert(InstX8632Blendvps::create(Func, Dest, Src0, Src1));
205 }
Jan Vounge4da26f2014-07-15 17:52:39 -0700206 void _br(InstX8632::BrCond Condition, CfgNode *TargetTrue,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700207 CfgNode *TargetFalse) {
208 Context.insert(
209 InstX8632Br::create(Func, TargetTrue, TargetFalse, Condition));
210 }
211 void _br(CfgNode *Target) {
212 Context.insert(InstX8632Br::create(Func, Target));
213 }
Jan Vounge4da26f2014-07-15 17:52:39 -0700214 void _br(InstX8632::BrCond Condition, CfgNode *Target) {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700215 Context.insert(InstX8632Br::create(Func, Target, Condition));
216 }
Jan Vounge4da26f2014-07-15 17:52:39 -0700217 void _br(InstX8632::BrCond Condition, InstX8632Label *Label) {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700218 Context.insert(InstX8632Br::create(Func, Label, Condition));
219 }
Jan Vounge4da26f2014-07-15 17:52:39 -0700220 void _bsf(Variable *Dest, Operand *Src0) {
221 Context.insert(InstX8632Bsf::create(Func, Dest, Src0));
222 }
223 void _bsr(Variable *Dest, Operand *Src0) {
224 Context.insert(InstX8632Bsr::create(Func, Dest, Src0));
225 }
Jan Voung7fa813b2014-07-18 13:01:08 -0700226 void _bswap(Variable *SrcDest) {
227 Context.insert(InstX8632Bswap::create(Func, SrcDest));
228 }
Matt Walaafeaee42014-08-07 13:47:30 -0700229 void _cbwdq(Variable *Dest, Operand *Src0) {
230 Context.insert(InstX8632Cbwdq::create(Func, Dest, Src0));
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700231 }
Jan Vounge4da26f2014-07-15 17:52:39 -0700232 void _cmov(Variable *Dest, Operand *Src0, InstX8632::BrCond Condition) {
233 Context.insert(InstX8632Cmov::create(Func, Dest, Src0, Condition));
234 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700235 void _cmp(Operand *Src0, Operand *Src1) {
236 Context.insert(InstX8632Icmp::create(Func, Src0, Src1));
237 }
Matt Walace0ca8f2014-07-24 12:34:20 -0700238 void _cmpps(Variable *Dest, Operand *Src0,
239 InstX8632Cmpps::CmppsCond Condition) {
240 Context.insert(InstX8632Cmpps::create(Func, Dest, Src0, Condition));
241 }
Jan Vounga3a01a22014-07-14 10:32:41 -0700242 void _cmpxchg(Operand *DestOrAddr, Variable *Eax, Variable *Desired,
243 bool Locked) {
244 Context.insert(
245 InstX8632Cmpxchg::create(Func, DestOrAddr, Eax, Desired, Locked));
246 // Mark eax as possibly modified by cmpxchg.
247 Context.insert(
248 InstFakeDef::create(Func, Eax, llvm::dyn_cast<Variable>(DestOrAddr)));
249 }
250 void _cmpxchg8b(OperandX8632 *Addr, Variable *Edx, Variable *Eax,
251 Variable *Ecx, Variable *Ebx, bool Locked) {
252 Context.insert(
253 InstX8632Cmpxchg8b::create(Func, Addr, Edx, Eax, Ecx, Ebx, Locked));
254 // Mark edx, and eax as possibly modified by cmpxchg8b.
255 Context.insert(InstFakeDef::create(Func, Edx));
256 Context.insert(InstFakeDef::create(Func, Eax));
257 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700258 void _cvt(Variable *Dest, Operand *Src0) {
259 Context.insert(InstX8632Cvt::create(Func, Dest, Src0));
260 }
261 void _div(Variable *Dest, Operand *Src0, Operand *Src1) {
262 Context.insert(InstX8632Div::create(Func, Dest, Src0, Src1));
263 }
Matt Wala8d1072e2014-07-11 15:43:51 -0700264 void _divps(Variable *Dest, Operand *Src0) {
265 Context.insert(InstX8632Divps::create(Func, Dest, Src0));
266 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700267 void _divss(Variable *Dest, Operand *Src0) {
268 Context.insert(InstX8632Divss::create(Func, Dest, Src0));
269 }
270 void _fld(Operand *Src0) { Context.insert(InstX8632Fld::create(Func, Src0)); }
271 void _fstp(Variable *Dest) {
272 Context.insert(InstX8632Fstp::create(Func, Dest));
273 }
274 void _idiv(Variable *Dest, Operand *Src0, Operand *Src1) {
275 Context.insert(InstX8632Idiv::create(Func, Dest, Src0, Src1));
276 }
277 void _imul(Variable *Dest, Operand *Src0) {
278 Context.insert(InstX8632Imul::create(Func, Dest, Src0));
279 }
Matt Wala0a450512014-07-30 12:44:39 -0700280 void _insertps(Variable *Dest, Operand *Src0, Operand *Src1) {
281 Context.insert(InstX8632Insertps::create(Func, Dest, Src0, Src1));
282 }
Matt Wala49889232014-07-18 12:45:09 -0700283 void _lea(Variable *Dest, Operand *Src0) {
284 Context.insert(InstX8632Lea::create(Func, Dest, Src0));
285 }
Jan Voung5cd240d2014-06-25 10:36:46 -0700286 void _mfence() { Context.insert(InstX8632Mfence::create(Func)); }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700287 // If Dest=NULL is passed in, then a new variable is created, marked
288 // as infinite register allocation weight, and returned through the
289 // in/out Dest argument.
290 void _mov(Variable *&Dest, Operand *Src0,
291 int32_t RegNum = Variable::NoRegister) {
292 if (Dest == NULL) {
293 Dest = legalizeToVar(Src0, false, RegNum);
294 } else {
295 Context.insert(InstX8632Mov::create(Func, Dest, Src0));
296 }
297 }
Matt Wala49889232014-07-18 12:45:09 -0700298 void _movd(Variable *Dest, Operand *Src0) {
299 Context.insert(InstX8632Movd::create(Func, Dest, Src0));
300 }
Matt Wala928f1292014-07-07 16:50:46 -0700301 void _movp(Variable *Dest, Operand *Src0) {
302 Context.insert(InstX8632Movp::create(Func, Dest, Src0));
303 }
Jan Voung5cd240d2014-06-25 10:36:46 -0700304 void _movq(Variable *Dest, Operand *Src0) {
305 Context.insert(InstX8632Movq::create(Func, Dest, Src0));
306 }
Matt Wala49889232014-07-18 12:45:09 -0700307 void _movss(Variable *Dest, Operand *Src0) {
308 Context.insert(InstX8632Movss::create(Func, Dest, Src0));
309 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700310 void _movsx(Variable *Dest, Operand *Src0) {
311 Context.insert(InstX8632Movsx::create(Func, Dest, Src0));
312 }
313 void _movzx(Variable *Dest, Operand *Src0) {
314 Context.insert(InstX8632Movzx::create(Func, Dest, Src0));
315 }
316 void _mul(Variable *Dest, Variable *Src0, Operand *Src1) {
317 Context.insert(InstX8632Mul::create(Func, Dest, Src0, Src1));
318 }
Matt Wala8d1072e2014-07-11 15:43:51 -0700319 void _mulps(Variable *Dest, Operand *Src0) {
320 Context.insert(InstX8632Mulps::create(Func, Dest, Src0));
321 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700322 void _mulss(Variable *Dest, Operand *Src0) {
323 Context.insert(InstX8632Mulss::create(Func, Dest, Src0));
324 }
Jan Vounga3a01a22014-07-14 10:32:41 -0700325 void _neg(Variable *SrcDest) {
326 Context.insert(InstX8632Neg::create(Func, SrcDest));
327 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700328 void _or(Variable *Dest, Operand *Src0) {
329 Context.insert(InstX8632Or::create(Func, Dest, Src0));
330 }
Matt Wala7fa22d82014-07-17 12:41:31 -0700331 void _padd(Variable *Dest, Operand *Src0) {
332 Context.insert(InstX8632Padd::create(Func, Dest, Src0));
333 }
Matt Wala83b80362014-07-16 10:21:30 -0700334 void _pand(Variable *Dest, Operand *Src0) {
335 Context.insert(InstX8632Pand::create(Func, Dest, Src0));
336 }
Matt Wala9cb61e22014-07-24 09:44:42 -0700337 void _pandn(Variable *Dest, Operand *Src0) {
338 Context.insert(InstX8632Pandn::create(Func, Dest, Src0));
339 }
Matt Wala0a450512014-07-30 12:44:39 -0700340 void _pblendvb(Variable *Dest, Operand *Src0, Operand *Src1) {
341 Context.insert(InstX8632Pblendvb::create(Func, Dest, Src0, Src1));
342 }
Matt Wala83b80362014-07-16 10:21:30 -0700343 void _pcmpeq(Variable *Dest, Operand *Src0) {
344 Context.insert(InstX8632Pcmpeq::create(Func, Dest, Src0));
345 }
346 void _pcmpgt(Variable *Dest, Operand *Src0) {
347 Context.insert(InstX8632Pcmpgt::create(Func, Dest, Src0));
348 }
Matt Wala0a450512014-07-30 12:44:39 -0700349 void _pextr(Variable *Dest, Operand *Src0, Operand *Src1) {
350 Context.insert(InstX8632Pextr::create(Func, Dest, Src0, Src1));
Matt Wala49889232014-07-18 12:45:09 -0700351 }
Matt Wala0a450512014-07-30 12:44:39 -0700352 void _pinsr(Variable *Dest, Operand *Src0, Operand *Src1) {
353 Context.insert(InstX8632Pinsr::create(Func, Dest, Src0, Src1));
Matt Wala49889232014-07-18 12:45:09 -0700354 }
Matt Wala0a450512014-07-30 12:44:39 -0700355 void _pmull(Variable *Dest, Operand *Src0) {
356 Context.insert(InstX8632Pmull::create(Func, Dest, Src0));
Matt Wala7fa22d82014-07-17 12:41:31 -0700357 }
358 void _pmuludq(Variable *Dest, Operand *Src0) {
359 Context.insert(InstX8632Pmuludq::create(Func, Dest, Src0));
360 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700361 void _pop(Variable *Dest) {
362 Context.insert(InstX8632Pop::create(Func, Dest));
363 }
Matt Wala7fa22d82014-07-17 12:41:31 -0700364 void _por(Variable *Dest, Operand *Src0) {
365 Context.insert(InstX8632Por::create(Func, Dest, Src0));
366 }
367 void _pshufd(Variable *Dest, Operand *Src0, Operand *Src1) {
368 Context.insert(InstX8632Pshufd::create(Func, Dest, Src0, Src1));
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700369 }
Matt Wala83b80362014-07-16 10:21:30 -0700370 void _psll(Variable *Dest, Operand *Src0) {
371 Context.insert(InstX8632Psll::create(Func, Dest, Src0));
372 }
373 void _psra(Variable *Dest, Operand *Src0) {
374 Context.insert(InstX8632Psra::create(Func, Dest, Src0));
375 }
376 void _psub(Variable *Dest, Operand *Src0) {
377 Context.insert(InstX8632Psub::create(Func, Dest, Src0));
378 }
Matt Wala7fa22d82014-07-17 12:41:31 -0700379 void _push(Operand *Src0, bool SuppressStackAdjustment = false) {
380 Context.insert(InstX8632Push::create(Func, Src0, SuppressStackAdjustment));
381 }
Matt Wala8d1072e2014-07-11 15:43:51 -0700382 void _pxor(Variable *Dest, Operand *Src0) {
383 Context.insert(InstX8632Pxor::create(Func, Dest, Src0));
384 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700385 void _ret(Variable *Src0 = NULL) {
386 Context.insert(InstX8632Ret::create(Func, Src0));
387 }
Jan Voung7fa813b2014-07-18 13:01:08 -0700388 void _rol(Variable *Dest, Operand *Src0) {
389 Context.insert(InstX8632Rol::create(Func, Dest, Src0));
390 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700391 void _sar(Variable *Dest, Operand *Src0) {
392 Context.insert(InstX8632Sar::create(Func, Dest, Src0));
393 }
394 void _sbb(Variable *Dest, Operand *Src0) {
395 Context.insert(InstX8632Sbb::create(Func, Dest, Src0));
396 }
397 void _shl(Variable *Dest, Operand *Src0) {
398 Context.insert(InstX8632Shl::create(Func, Dest, Src0));
399 }
400 void _shld(Variable *Dest, Variable *Src0, Variable *Src1) {
401 Context.insert(InstX8632Shld::create(Func, Dest, Src0, Src1));
402 }
403 void _shr(Variable *Dest, Operand *Src0) {
404 Context.insert(InstX8632Shr::create(Func, Dest, Src0));
405 }
406 void _shrd(Variable *Dest, Variable *Src0, Variable *Src1) {
407 Context.insert(InstX8632Shrd::create(Func, Dest, Src0, Src1));
408 }
Matt Wala7fa22d82014-07-17 12:41:31 -0700409 void _shufps(Variable *Dest, Operand *Src0, Operand *Src1) {
410 Context.insert(InstX8632Shufps::create(Func, Dest, Src0, Src1));
411 }
Jan Voungf37fbbe2014-07-09 16:13:13 -0700412 void _sqrtss(Variable *Dest, Operand *Src0) {
413 Context.insert(InstX8632Sqrtss::create(Func, Dest, Src0));
414 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700415 void _store(Operand *Value, OperandX8632 *Mem) {
416 Context.insert(InstX8632Store::create(Func, Value, Mem));
417 }
Matt Wala105b7042014-08-11 19:56:19 -0700418 void _storep(Operand *Value, OperandX8632 *Mem) {
419 Context.insert(InstX8632StoreP::create(Func, Value, Mem));
420 }
Jan Voung5cd240d2014-06-25 10:36:46 -0700421 void _storeq(Operand *Value, OperandX8632 *Mem) {
422 Context.insert(InstX8632StoreQ::create(Func, Value, Mem));
423 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700424 void _sub(Variable *Dest, Operand *Src0) {
425 Context.insert(InstX8632Sub::create(Func, Dest, Src0));
426 }
Matt Wala8d1072e2014-07-11 15:43:51 -0700427 void _subps(Variable *Dest, Operand *Src0) {
428 Context.insert(InstX8632Subps::create(Func, Dest, Src0));
429 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700430 void _subss(Variable *Dest, Operand *Src0) {
431 Context.insert(InstX8632Subss::create(Func, Dest, Src0));
432 }
433 void _test(Operand *Src0, Operand *Src1) {
434 Context.insert(InstX8632Test::create(Func, Src0, Src1));
435 }
436 void _ucomiss(Operand *Src0, Operand *Src1) {
437 Context.insert(InstX8632Ucomiss::create(Func, Src0, Src1));
438 }
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700439 void _ud2() { Context.insert(InstX8632UD2::create(Func)); }
Jan Voung5cd240d2014-06-25 10:36:46 -0700440 void _xadd(Operand *Dest, Variable *Src, bool Locked) {
441 Context.insert(InstX8632Xadd::create(Func, Dest, Src, Locked));
442 // The xadd exchanges Dest and Src (modifying Src).
443 // Model that update with a FakeDef.
Jan Vounga3a01a22014-07-14 10:32:41 -0700444 Context.insert(
445 InstFakeDef::create(Func, Src, llvm::dyn_cast<Variable>(Dest)));
446 }
447 void _xchg(Operand *Dest, Variable *Src) {
448 Context.insert(InstX8632Xchg::create(Func, Dest, Src));
449 // The xchg modifies Dest and Src -- model that update with a FakeDef.
450 Context.insert(
451 InstFakeDef::create(Func, Src, llvm::dyn_cast<Variable>(Dest)));
Jan Voung5cd240d2014-06-25 10:36:46 -0700452 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700453 void _xor(Variable *Dest, Operand *Src0) {
454 Context.insert(InstX8632Xor::create(Func, Dest, Src0));
455 }
456
Matt Wala0a450512014-07-30 12:44:39 -0700457 const X86InstructionSet InstructionSet;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700458 bool IsEbpBasedFrame;
Matt Wala105b7042014-08-11 19:56:19 -0700459 bool NeedsStackAlignment;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700460 size_t FrameSizeLocals;
461 size_t LocalsSizeBytes;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700462 llvm::SmallBitVector TypeToRegisterSet[IceType_NUM];
463 llvm::SmallBitVector ScratchRegs;
464 llvm::SmallBitVector RegsUsed;
465 SizeT NextLabelNumber;
466 bool ComputedLiveRanges;
467 VarList PhysicalRegisters;
468 static IceString RegNames[];
469
470private:
471 TargetX8632(const TargetX8632 &) LLVM_DELETED_FUNCTION;
472 TargetX8632 &operator=(const TargetX8632 &) LLVM_DELETED_FUNCTION;
473 virtual ~TargetX8632() {}
Jim Stichnothf61d5b22014-05-23 13:31:24 -0700474 template <typename T> void emitConstantPool() const;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700475};
476
Jim Stichnothde4ca712014-06-29 08:13:48 -0700477class TargetGlobalInitX8632 : public TargetGlobalInitLowering {
478public:
479 static TargetGlobalInitLowering *create(GlobalContext *Ctx) {
480 return new TargetGlobalInitX8632(Ctx);
481 }
482 virtual void lower(const IceString &Name, SizeT Align, bool IsInternal,
483 bool IsConst, bool IsZeroInitializer, SizeT Size,
484 const char *Data, bool DisableTranslation);
485
486protected:
487 TargetGlobalInitX8632(GlobalContext *Ctx);
488
489private:
490 TargetGlobalInitX8632(const TargetGlobalInitX8632 &) LLVM_DELETED_FUNCTION;
491 TargetGlobalInitX8632 &
492 operator=(const TargetGlobalInitX8632 &) LLVM_DELETED_FUNCTION;
493 virtual ~TargetGlobalInitX8632() {}
494};
495
Matt Wala928f1292014-07-07 16:50:46 -0700496template <> void ConstantInteger::emit(GlobalContext *Ctx) const;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700497template <> void ConstantFloat::emit(GlobalContext *Ctx) const;
498template <> void ConstantDouble::emit(GlobalContext *Ctx) const;
Jim Stichnothf61d5b22014-05-23 13:31:24 -0700499
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700500} // end of namespace Ice
501
502#endif // SUBZERO_SRC_ICETARGETLOWERINGX8632_H