blob: 71062cc27df4938528fdf30790867e89aaf9175d [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"
Jan Voung8acded02014-09-22 18:02:25 -070021#include "assembler_ia32.h"
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070022#include "IceInstX8632.h"
Jan Voungbd385e42014-09-18 18:18:10 -070023#include "IceRegistersX8632.h"
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070024
25namespace Ice {
26
27class TargetX8632 : public TargetLowering {
28public:
29 static TargetX8632 *create(Cfg *Func) { return new TargetX8632(Func); }
30
31 virtual void translateOm1();
Jim Stichnothd97c7df2014-06-04 11:57:08 -070032 virtual void translateO2();
Jim Stichnothff9c7062014-09-18 04:50:49 -070033 virtual bool doBranchOpt(Inst *I, const CfgNode *NextNode);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070034
35 virtual Variable *getPhysicalRegister(SizeT RegNum);
36 virtual IceString getRegName(SizeT RegNum, Type Ty) const;
37 virtual llvm::SmallBitVector getRegisterSet(RegSetMask Include,
38 RegSetMask Exclude) const;
39 virtual const llvm::SmallBitVector &getRegisterSetForType(Type Ty) const {
40 return TypeToRegisterSet[Ty];
41 }
42 virtual bool hasFramePointer() const { return IsEbpBasedFrame; }
43 virtual SizeT getFrameOrStackReg() const {
Jan Voungbd385e42014-09-18 18:18:10 -070044 return IsEbpBasedFrame ? RegX8632::Reg_ebp : RegX8632::Reg_esp;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070045 }
Matt Walad4799f42014-08-14 14:24:12 -070046 virtual size_t typeWidthInBytesOnStack(Type Ty) const {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070047 // Round up to the next multiple of 4 bytes. In particular, i1,
48 // i8, and i16 are rounded up to 4 bytes.
49 return (typeWidthInBytes(Ty) + 3) & ~3;
50 }
Jan Voungb17f61d2014-08-28 16:00:53 -070051 virtual SizeT getBundleAlignLog2Bytes() const { return 5; }
52 virtual llvm::ArrayRef<uint8_t> getNonExecBundlePadding() const {
53 static const uint8_t Padding[] = { 0xF4 };
54 return llvm::ArrayRef<uint8_t>(Padding, 1);
55 }
Jim Stichnoth144cdce2014-09-22 16:02:59 -070056 virtual void emitVariable(const Variable *Var) const;
Matt Wala45a06232014-07-09 16:33:22 -070057 virtual void lowerArguments();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070058 virtual void addProlog(CfgNode *Node);
59 virtual void addEpilog(CfgNode *Node);
Jim Stichnothf61d5b22014-05-23 13:31:24 -070060 virtual void emitConstants() const;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070061 SizeT makeNextLabelNumber() { return NextLabelNumber++; }
62 // Ensure that a 64-bit Variable has been split into 2 32-bit
63 // Variables, creating them if necessary. This is needed for all
64 // I64 operations, and it is needed for pushing F64 arguments for
65 // function calls using the 32-bit push instruction (though the
66 // latter could be done by directly writing to the stack).
67 void split64(Variable *Var);
Matt Wala45a06232014-07-09 16:33:22 -070068 void finishArgumentLowering(Variable *Arg, Variable *FramePtr,
69 size_t BasicFrameOffset, size_t &InArgsSizeBytes);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070070 Operand *loOperand(Operand *Operand);
71 Operand *hiOperand(Operand *Operand);
Jan Voung8acded02014-09-22 18:02:25 -070072 x86::Address stackVarToAsmOperand(const Variable *Var) const;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070073
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();
Matt Walac3302742014-08-15 16:21:56 -0700107 virtual void randomlyInsertNop(float Probability);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700108
Jan Voungc820ddf2014-07-29 14:38:51 -0700109 // Naive lowering of cmpxchg.
Jan Vounga3a01a22014-07-14 10:32:41 -0700110 void lowerAtomicCmpxchg(Variable *DestPrev, Operand *Ptr, Operand *Expected,
111 Operand *Desired);
Jan Voungc820ddf2014-07-29 14:38:51 -0700112 // Attempt a more optimized lowering of cmpxchg. Returns true if optimized.
113 bool tryOptimizedCmpxchgCmpBr(Variable *DestPrev, Operand *Ptr,
114 Operand *Expected, Operand *Desired);
Jan Voung5cd240d2014-06-25 10:36:46 -0700115 void lowerAtomicRMW(Variable *Dest, uint32_t Operation, Operand *Ptr,
116 Operand *Val);
Jan Vounge4da26f2014-07-15 17:52:39 -0700117 void lowerCountZeros(bool Cttz, Type Ty, Variable *Dest, Operand *FirstVal,
118 Operand *SecondVal);
Jan Voung5cd240d2014-06-25 10:36:46 -0700119
Jan Vounga3a01a22014-07-14 10:32:41 -0700120 typedef void (TargetX8632::*LowerBinOp)(Variable *, Operand *);
121 void expandAtomicRMWAsCmpxchg(LowerBinOp op_lo, LowerBinOp op_hi,
122 Variable *Dest, Operand *Ptr, Operand *Val);
123
Matt Walace0ca8f2014-07-24 12:34:20 -0700124 void eliminateNextVectorSextInstruction(Variable *SignExtendedResult);
125
Matt Walaafeaee42014-08-07 13:47:30 -0700126 void scalarizeArithmetic(InstArithmetic::OpKind K, Variable *Dest,
127 Operand *Src0, Operand *Src1);
128
Matt Walad4799f42014-08-14 14:24:12 -0700129 void sortByAlignment(VarList &Dest, const VarList &Source) const;
130
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700131 // Operand legalization helpers. To deal with address mode
132 // constraints, the helpers will create a new Operand and emit
133 // instructions that guarantee that the Operand kind is one of those
134 // indicated by the LegalMask (a bitmask of allowed kinds). If the
135 // input Operand is known to already meet the constraints, it may be
136 // simply returned as the result, without creating any new
137 // instructions or operands.
138 enum OperandLegalization {
139 Legal_None = 0,
140 Legal_Reg = 1 << 0, // physical register, not stack location
141 Legal_Imm = 1 << 1,
142 Legal_Mem = 1 << 2, // includes [eax+4*ecx] as well as [esp+12]
Jim Stichnothde4ca712014-06-29 08:13:48 -0700143 // TODO(stichnot): LEAHACK: remove Legal_Reloc once a proper
144 // emitter is used.
145 Legal_Reloc = 1 << 3,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700146 Legal_All = ~Legal_None
147 };
148 typedef uint32_t LegalMask;
Jim Stichnothde4ca712014-06-29 08:13:48 -0700149 Operand *legalize(Operand *From, LegalMask Allowed = Legal_All & ~Legal_Reloc,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700150 bool AllowOverlap = false,
151 int32_t RegNum = Variable::NoRegister);
152 Variable *legalizeToVar(Operand *From, bool AllowOverlap = false,
153 int32_t RegNum = Variable::NoRegister);
Jan Voung5cd240d2014-06-25 10:36:46 -0700154 // Turn a pointer operand into a memory operand that can be
155 // used by a real load/store operation. Legalizes the operand as well.
156 // This is a nop if the operand is already a legal memory operand.
157 OperandX8632Mem *FormMemoryOperand(Operand *Ptr, Type Ty);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700158
159 Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister);
160 InstCall *makeHelperCall(const IceString &Name, Variable *Dest,
161 SizeT MaxSrcs) {
162 bool SuppressMangling = true;
Matt Walaad8f7262014-07-14 17:37:37 -0700163 const Type FunctionPointerType = IceType_i32;
164 Constant *CallTarget =
165 Ctx->getConstantSym(FunctionPointerType, 0, Name, SuppressMangling);
Karl Schimpf8df26f32014-09-19 09:33:26 -0700166 InstCall *Call = InstCall::create(Func, MaxSrcs, Dest, CallTarget, false);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700167 return Call;
168 }
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700169 static Type stackSlotType();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700170
Matt Wala928f1292014-07-07 16:50:46 -0700171 Variable *copyToReg(Operand *Src, int32_t RegNum = Variable::NoRegister);
172
Matt Wala83b80362014-07-16 10:21:30 -0700173 // Returns a vector in a register with the given constant entries.
174 Variable *makeVectorOfZeros(Type Ty, int32_t RegNum = Variable::NoRegister);
175 Variable *makeVectorOfOnes(Type Ty, int32_t RegNum = Variable::NoRegister);
Matt Wala9a0168a2014-07-23 14:56:10 -0700176 Variable *makeVectorOfMinusOnes(Type Ty,
177 int32_t RegNum = Variable::NoRegister);
178 Variable *makeVectorOfHighOrderBits(Type Ty,
179 int32_t RegNum = Variable::NoRegister);
Matt Wala83b80362014-07-16 10:21:30 -0700180
Matt Wala49889232014-07-18 12:45:09 -0700181 // Return a memory operand corresponding to a stack allocated Variable.
182 OperandX8632Mem *getMemoryOperandForStackSlot(Type Ty, Variable *Slot,
183 uint32_t Offset = 0);
184
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700185 // The following are helpers that insert lowered x86 instructions
186 // with minimal syntactic overhead, so that the lowering code can
187 // look as close to assembly as practical.
188 void _adc(Variable *Dest, Operand *Src0) {
189 Context.insert(InstX8632Adc::create(Func, Dest, Src0));
190 }
191 void _add(Variable *Dest, Operand *Src0) {
192 Context.insert(InstX8632Add::create(Func, Dest, Src0));
193 }
Matt Wala105b7042014-08-11 19:56:19 -0700194 void _adjust_stack(int32_t Amount) {
Jim Stichnoth144cdce2014-09-22 16:02:59 -0700195 Context.insert(InstX8632AdjustStack::create(
196 Func, Amount, getPhysicalRegister(RegX8632::Reg_esp)));
Matt Wala105b7042014-08-11 19:56:19 -0700197 }
Matt Wala8d1072e2014-07-11 15:43:51 -0700198 void _addps(Variable *Dest, Operand *Src0) {
199 Context.insert(InstX8632Addps::create(Func, Dest, Src0));
200 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700201 void _addss(Variable *Dest, Operand *Src0) {
202 Context.insert(InstX8632Addss::create(Func, Dest, Src0));
203 }
204 void _and(Variable *Dest, Operand *Src0) {
205 Context.insert(InstX8632And::create(Func, Dest, Src0));
206 }
Matt Wala0a450512014-07-30 12:44:39 -0700207 void _blendvps(Variable *Dest, Operand *Src0, Operand *Src1) {
208 Context.insert(InstX8632Blendvps::create(Func, Dest, Src0, Src1));
209 }
Jan Voungbd385e42014-09-18 18:18:10 -0700210 void _br(CondX86::BrCond Condition, CfgNode *TargetTrue,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700211 CfgNode *TargetFalse) {
212 Context.insert(
213 InstX8632Br::create(Func, TargetTrue, TargetFalse, Condition));
214 }
215 void _br(CfgNode *Target) {
216 Context.insert(InstX8632Br::create(Func, Target));
217 }
Jan Voungbd385e42014-09-18 18:18:10 -0700218 void _br(CondX86::BrCond Condition, CfgNode *Target) {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700219 Context.insert(InstX8632Br::create(Func, Target, Condition));
220 }
Jan Voungbd385e42014-09-18 18:18:10 -0700221 void _br(CondX86::BrCond Condition, InstX8632Label *Label) {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700222 Context.insert(InstX8632Br::create(Func, Label, Condition));
223 }
Jan Vounge4da26f2014-07-15 17:52:39 -0700224 void _bsf(Variable *Dest, Operand *Src0) {
225 Context.insert(InstX8632Bsf::create(Func, Dest, Src0));
226 }
227 void _bsr(Variable *Dest, Operand *Src0) {
228 Context.insert(InstX8632Bsr::create(Func, Dest, Src0));
229 }
Jan Voung7fa813b2014-07-18 13:01:08 -0700230 void _bswap(Variable *SrcDest) {
231 Context.insert(InstX8632Bswap::create(Func, SrcDest));
232 }
Matt Walaafeaee42014-08-07 13:47:30 -0700233 void _cbwdq(Variable *Dest, Operand *Src0) {
234 Context.insert(InstX8632Cbwdq::create(Func, Dest, Src0));
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700235 }
Jan Voungbd385e42014-09-18 18:18:10 -0700236 void _cmov(Variable *Dest, Operand *Src0, CondX86::BrCond Condition) {
Jan Vounge4da26f2014-07-15 17:52:39 -0700237 Context.insert(InstX8632Cmov::create(Func, Dest, Src0, Condition));
238 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700239 void _cmp(Operand *Src0, Operand *Src1) {
240 Context.insert(InstX8632Icmp::create(Func, Src0, Src1));
241 }
Jan Voungbd385e42014-09-18 18:18:10 -0700242 void _cmpps(Variable *Dest, Operand *Src0, CondX86::CmppsCond Condition) {
Matt Walace0ca8f2014-07-24 12:34:20 -0700243 Context.insert(InstX8632Cmpps::create(Func, Dest, Src0, Condition));
244 }
Jan Vounga3a01a22014-07-14 10:32:41 -0700245 void _cmpxchg(Operand *DestOrAddr, Variable *Eax, Variable *Desired,
246 bool Locked) {
247 Context.insert(
248 InstX8632Cmpxchg::create(Func, DestOrAddr, Eax, Desired, Locked));
249 // Mark eax as possibly modified by cmpxchg.
250 Context.insert(
251 InstFakeDef::create(Func, Eax, llvm::dyn_cast<Variable>(DestOrAddr)));
252 }
253 void _cmpxchg8b(OperandX8632 *Addr, Variable *Edx, Variable *Eax,
254 Variable *Ecx, Variable *Ebx, bool Locked) {
255 Context.insert(
256 InstX8632Cmpxchg8b::create(Func, Addr, Edx, Eax, Ecx, Ebx, Locked));
257 // Mark edx, and eax as possibly modified by cmpxchg8b.
258 Context.insert(InstFakeDef::create(Func, Edx));
259 Context.insert(InstFakeDef::create(Func, Eax));
260 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700261 void _cvt(Variable *Dest, Operand *Src0) {
Jim Stichnothb63cd882014-09-08 10:47:23 -0700262 const bool Trunc = false;
263 Context.insert(InstX8632Cvt::create(Func, Dest, Src0, Trunc));
264 }
265 void _cvtt(Variable *Dest, Operand *Src0) {
266 const bool Trunc = true;
267 Context.insert(InstX8632Cvt::create(Func, Dest, Src0, Trunc));
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700268 }
269 void _div(Variable *Dest, Operand *Src0, Operand *Src1) {
270 Context.insert(InstX8632Div::create(Func, Dest, Src0, Src1));
271 }
Matt Wala8d1072e2014-07-11 15:43:51 -0700272 void _divps(Variable *Dest, Operand *Src0) {
273 Context.insert(InstX8632Divps::create(Func, Dest, Src0));
274 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700275 void _divss(Variable *Dest, Operand *Src0) {
276 Context.insert(InstX8632Divss::create(Func, Dest, Src0));
277 }
278 void _fld(Operand *Src0) { Context.insert(InstX8632Fld::create(Func, Src0)); }
279 void _fstp(Variable *Dest) {
280 Context.insert(InstX8632Fstp::create(Func, Dest));
281 }
282 void _idiv(Variable *Dest, Operand *Src0, Operand *Src1) {
283 Context.insert(InstX8632Idiv::create(Func, Dest, Src0, Src1));
284 }
285 void _imul(Variable *Dest, Operand *Src0) {
286 Context.insert(InstX8632Imul::create(Func, Dest, Src0));
287 }
Matt Wala0a450512014-07-30 12:44:39 -0700288 void _insertps(Variable *Dest, Operand *Src0, Operand *Src1) {
289 Context.insert(InstX8632Insertps::create(Func, Dest, Src0, Src1));
290 }
Matt Wala49889232014-07-18 12:45:09 -0700291 void _lea(Variable *Dest, Operand *Src0) {
292 Context.insert(InstX8632Lea::create(Func, Dest, Src0));
293 }
Jan Voung5cd240d2014-06-25 10:36:46 -0700294 void _mfence() { Context.insert(InstX8632Mfence::create(Func)); }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700295 // If Dest=NULL is passed in, then a new variable is created, marked
296 // as infinite register allocation weight, and returned through the
297 // in/out Dest argument.
298 void _mov(Variable *&Dest, Operand *Src0,
299 int32_t RegNum = Variable::NoRegister) {
300 if (Dest == NULL) {
301 Dest = legalizeToVar(Src0, false, RegNum);
302 } else {
303 Context.insert(InstX8632Mov::create(Func, Dest, Src0));
304 }
305 }
Matt Wala49889232014-07-18 12:45:09 -0700306 void _movd(Variable *Dest, Operand *Src0) {
307 Context.insert(InstX8632Movd::create(Func, Dest, Src0));
308 }
Matt Wala928f1292014-07-07 16:50:46 -0700309 void _movp(Variable *Dest, Operand *Src0) {
310 Context.insert(InstX8632Movp::create(Func, Dest, Src0));
311 }
Jan Voung5cd240d2014-06-25 10:36:46 -0700312 void _movq(Variable *Dest, Operand *Src0) {
313 Context.insert(InstX8632Movq::create(Func, Dest, Src0));
314 }
Matt Wala49889232014-07-18 12:45:09 -0700315 void _movss(Variable *Dest, Operand *Src0) {
316 Context.insert(InstX8632Movss::create(Func, Dest, Src0));
317 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700318 void _movsx(Variable *Dest, Operand *Src0) {
319 Context.insert(InstX8632Movsx::create(Func, Dest, Src0));
320 }
321 void _movzx(Variable *Dest, Operand *Src0) {
322 Context.insert(InstX8632Movzx::create(Func, Dest, Src0));
323 }
324 void _mul(Variable *Dest, Variable *Src0, Operand *Src1) {
325 Context.insert(InstX8632Mul::create(Func, Dest, Src0, Src1));
326 }
Matt Wala8d1072e2014-07-11 15:43:51 -0700327 void _mulps(Variable *Dest, Operand *Src0) {
328 Context.insert(InstX8632Mulps::create(Func, Dest, Src0));
329 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700330 void _mulss(Variable *Dest, Operand *Src0) {
331 Context.insert(InstX8632Mulss::create(Func, Dest, Src0));
332 }
Jan Vounga3a01a22014-07-14 10:32:41 -0700333 void _neg(Variable *SrcDest) {
334 Context.insert(InstX8632Neg::create(Func, SrcDest));
335 }
Matt Walac3302742014-08-15 16:21:56 -0700336 void _nop(SizeT Variant) {
337 Context.insert(InstX8632Nop::create(Func, Variant));
338 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700339 void _or(Variable *Dest, Operand *Src0) {
340 Context.insert(InstX8632Or::create(Func, Dest, Src0));
341 }
Matt Wala7fa22d82014-07-17 12:41:31 -0700342 void _padd(Variable *Dest, Operand *Src0) {
343 Context.insert(InstX8632Padd::create(Func, Dest, Src0));
344 }
Matt Wala83b80362014-07-16 10:21:30 -0700345 void _pand(Variable *Dest, Operand *Src0) {
346 Context.insert(InstX8632Pand::create(Func, Dest, Src0));
347 }
Matt Wala9cb61e22014-07-24 09:44:42 -0700348 void _pandn(Variable *Dest, Operand *Src0) {
349 Context.insert(InstX8632Pandn::create(Func, Dest, Src0));
350 }
Matt Wala0a450512014-07-30 12:44:39 -0700351 void _pblendvb(Variable *Dest, Operand *Src0, Operand *Src1) {
352 Context.insert(InstX8632Pblendvb::create(Func, Dest, Src0, Src1));
353 }
Matt Wala83b80362014-07-16 10:21:30 -0700354 void _pcmpeq(Variable *Dest, Operand *Src0) {
355 Context.insert(InstX8632Pcmpeq::create(Func, Dest, Src0));
356 }
357 void _pcmpgt(Variable *Dest, Operand *Src0) {
358 Context.insert(InstX8632Pcmpgt::create(Func, Dest, Src0));
359 }
Matt Wala0a450512014-07-30 12:44:39 -0700360 void _pextr(Variable *Dest, Operand *Src0, Operand *Src1) {
361 Context.insert(InstX8632Pextr::create(Func, Dest, Src0, Src1));
Matt Wala49889232014-07-18 12:45:09 -0700362 }
Matt Wala0a450512014-07-30 12:44:39 -0700363 void _pinsr(Variable *Dest, Operand *Src0, Operand *Src1) {
364 Context.insert(InstX8632Pinsr::create(Func, Dest, Src0, Src1));
Matt Wala49889232014-07-18 12:45:09 -0700365 }
Matt Wala0a450512014-07-30 12:44:39 -0700366 void _pmull(Variable *Dest, Operand *Src0) {
367 Context.insert(InstX8632Pmull::create(Func, Dest, Src0));
Matt Wala7fa22d82014-07-17 12:41:31 -0700368 }
369 void _pmuludq(Variable *Dest, Operand *Src0) {
370 Context.insert(InstX8632Pmuludq::create(Func, Dest, Src0));
371 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700372 void _pop(Variable *Dest) {
373 Context.insert(InstX8632Pop::create(Func, Dest));
374 }
Matt Wala7fa22d82014-07-17 12:41:31 -0700375 void _por(Variable *Dest, Operand *Src0) {
376 Context.insert(InstX8632Por::create(Func, Dest, Src0));
377 }
378 void _pshufd(Variable *Dest, Operand *Src0, Operand *Src1) {
379 Context.insert(InstX8632Pshufd::create(Func, Dest, Src0, Src1));
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700380 }
Matt Wala83b80362014-07-16 10:21:30 -0700381 void _psll(Variable *Dest, Operand *Src0) {
382 Context.insert(InstX8632Psll::create(Func, Dest, Src0));
383 }
384 void _psra(Variable *Dest, Operand *Src0) {
385 Context.insert(InstX8632Psra::create(Func, Dest, Src0));
386 }
387 void _psub(Variable *Dest, Operand *Src0) {
388 Context.insert(InstX8632Psub::create(Func, Dest, Src0));
389 }
Matt Wala7fa22d82014-07-17 12:41:31 -0700390 void _push(Operand *Src0, bool SuppressStackAdjustment = false) {
391 Context.insert(InstX8632Push::create(Func, Src0, SuppressStackAdjustment));
392 }
Matt Wala8d1072e2014-07-11 15:43:51 -0700393 void _pxor(Variable *Dest, Operand *Src0) {
394 Context.insert(InstX8632Pxor::create(Func, Dest, Src0));
395 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700396 void _ret(Variable *Src0 = NULL) {
397 Context.insert(InstX8632Ret::create(Func, Src0));
398 }
Jan Voung7fa813b2014-07-18 13:01:08 -0700399 void _rol(Variable *Dest, Operand *Src0) {
400 Context.insert(InstX8632Rol::create(Func, Dest, Src0));
401 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700402 void _sar(Variable *Dest, Operand *Src0) {
403 Context.insert(InstX8632Sar::create(Func, Dest, Src0));
404 }
405 void _sbb(Variable *Dest, Operand *Src0) {
406 Context.insert(InstX8632Sbb::create(Func, Dest, Src0));
407 }
408 void _shl(Variable *Dest, Operand *Src0) {
409 Context.insert(InstX8632Shl::create(Func, Dest, Src0));
410 }
411 void _shld(Variable *Dest, Variable *Src0, Variable *Src1) {
412 Context.insert(InstX8632Shld::create(Func, Dest, Src0, Src1));
413 }
414 void _shr(Variable *Dest, Operand *Src0) {
415 Context.insert(InstX8632Shr::create(Func, Dest, Src0));
416 }
417 void _shrd(Variable *Dest, Variable *Src0, Variable *Src1) {
418 Context.insert(InstX8632Shrd::create(Func, Dest, Src0, Src1));
419 }
Matt Wala7fa22d82014-07-17 12:41:31 -0700420 void _shufps(Variable *Dest, Operand *Src0, Operand *Src1) {
421 Context.insert(InstX8632Shufps::create(Func, Dest, Src0, Src1));
422 }
Jan Voungf37fbbe2014-07-09 16:13:13 -0700423 void _sqrtss(Variable *Dest, Operand *Src0) {
424 Context.insert(InstX8632Sqrtss::create(Func, Dest, Src0));
425 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700426 void _store(Operand *Value, OperandX8632 *Mem) {
427 Context.insert(InstX8632Store::create(Func, Value, Mem));
428 }
Matt Wala105b7042014-08-11 19:56:19 -0700429 void _storep(Operand *Value, OperandX8632 *Mem) {
430 Context.insert(InstX8632StoreP::create(Func, Value, Mem));
431 }
Jan Voung5cd240d2014-06-25 10:36:46 -0700432 void _storeq(Operand *Value, OperandX8632 *Mem) {
433 Context.insert(InstX8632StoreQ::create(Func, Value, Mem));
434 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700435 void _sub(Variable *Dest, Operand *Src0) {
436 Context.insert(InstX8632Sub::create(Func, Dest, Src0));
437 }
Matt Wala8d1072e2014-07-11 15:43:51 -0700438 void _subps(Variable *Dest, Operand *Src0) {
439 Context.insert(InstX8632Subps::create(Func, Dest, Src0));
440 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700441 void _subss(Variable *Dest, Operand *Src0) {
442 Context.insert(InstX8632Subss::create(Func, Dest, Src0));
443 }
444 void _test(Operand *Src0, Operand *Src1) {
445 Context.insert(InstX8632Test::create(Func, Src0, Src1));
446 }
447 void _ucomiss(Operand *Src0, Operand *Src1) {
448 Context.insert(InstX8632Ucomiss::create(Func, Src0, Src1));
449 }
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700450 void _ud2() { Context.insert(InstX8632UD2::create(Func)); }
Jan Voung5cd240d2014-06-25 10:36:46 -0700451 void _xadd(Operand *Dest, Variable *Src, bool Locked) {
452 Context.insert(InstX8632Xadd::create(Func, Dest, Src, Locked));
453 // The xadd exchanges Dest and Src (modifying Src).
454 // Model that update with a FakeDef.
Jan Vounga3a01a22014-07-14 10:32:41 -0700455 Context.insert(
456 InstFakeDef::create(Func, Src, llvm::dyn_cast<Variable>(Dest)));
457 }
458 void _xchg(Operand *Dest, Variable *Src) {
459 Context.insert(InstX8632Xchg::create(Func, Dest, Src));
460 // The xchg modifies Dest and Src -- model that update with a FakeDef.
461 Context.insert(
462 InstFakeDef::create(Func, Src, llvm::dyn_cast<Variable>(Dest)));
Jan Voung5cd240d2014-06-25 10:36:46 -0700463 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700464 void _xor(Variable *Dest, Operand *Src0) {
465 Context.insert(InstX8632Xor::create(Func, Dest, Src0));
466 }
467
Matt Wala0a450512014-07-30 12:44:39 -0700468 const X86InstructionSet InstructionSet;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700469 bool IsEbpBasedFrame;
Matt Wala105b7042014-08-11 19:56:19 -0700470 bool NeedsStackAlignment;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700471 size_t FrameSizeLocals;
Matt Walad4799f42014-08-14 14:24:12 -0700472 size_t SpillAreaSizeBytes;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700473 llvm::SmallBitVector TypeToRegisterSet[IceType_NUM];
474 llvm::SmallBitVector ScratchRegs;
475 llvm::SmallBitVector RegsUsed;
476 SizeT NextLabelNumber;
477 bool ComputedLiveRanges;
478 VarList PhysicalRegisters;
479 static IceString RegNames[];
480
481private:
482 TargetX8632(const TargetX8632 &) LLVM_DELETED_FUNCTION;
483 TargetX8632 &operator=(const TargetX8632 &) LLVM_DELETED_FUNCTION;
484 virtual ~TargetX8632() {}
Jim Stichnothf61d5b22014-05-23 13:31:24 -0700485 template <typename T> void emitConstantPool() const;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700486};
487
Jim Stichnothde4ca712014-06-29 08:13:48 -0700488class TargetGlobalInitX8632 : public TargetGlobalInitLowering {
489public:
490 static TargetGlobalInitLowering *create(GlobalContext *Ctx) {
491 return new TargetGlobalInitX8632(Ctx);
492 }
493 virtual void lower(const IceString &Name, SizeT Align, bool IsInternal,
494 bool IsConst, bool IsZeroInitializer, SizeT Size,
495 const char *Data, bool DisableTranslation);
496
497protected:
498 TargetGlobalInitX8632(GlobalContext *Ctx);
499
500private:
501 TargetGlobalInitX8632(const TargetGlobalInitX8632 &) LLVM_DELETED_FUNCTION;
502 TargetGlobalInitX8632 &
503 operator=(const TargetGlobalInitX8632 &) LLVM_DELETED_FUNCTION;
504 virtual ~TargetGlobalInitX8632() {}
505};
506
Jan Voungbc004632014-09-16 15:09:10 -0700507template <> void ConstantInteger32::emit(GlobalContext *Ctx) const;
508template <> void ConstantInteger64::emit(GlobalContext *Ctx) const;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700509template <> void ConstantFloat::emit(GlobalContext *Ctx) const;
510template <> void ConstantDouble::emit(GlobalContext *Ctx) const;
Jim Stichnothf61d5b22014-05-23 13:31:24 -0700511
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700512} // end of namespace Ice
513
514#endif // SUBZERO_SRC_ICETARGETLOWERINGX8632_H