blob: fca29c43d7f4eb65f20f1cc842a26aea0ffeeb9a [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
Jan Voung8acded02014-09-22 18:02:25 -070019#include "assembler_ia32.h"
Jim Stichnotha18cc9c2014-09-30 19:10:22 -070020#include "IceDefs.h"
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070021#include "IceInstX8632.h"
Jan Voungbd385e42014-09-18 18:18:10 -070022#include "IceRegistersX8632.h"
Jim Stichnotha18cc9c2014-09-30 19:10:22 -070023#include "IceTargetLowering.h"
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070024
25namespace Ice {
26
27class TargetX8632 : public TargetLowering {
Jim Stichnoth7b451a92014-10-15 14:39:23 -070028 TargetX8632(const TargetX8632 &) = delete;
29 TargetX8632 &operator=(const TargetX8632 &) = delete;
30
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070031public:
32 static TargetX8632 *create(Cfg *Func) { return new TargetX8632(Func); }
33
Jim Stichnothb56c8f42014-09-26 09:28:46 -070034 void translateOm1() override;
35 void translateO2() override;
36 bool doBranchOpt(Inst *I, const CfgNode *NextNode) override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070037
Jim Stichnoth3d44fe82014-11-01 10:10:18 -070038 SizeT getNumRegisters() const override { return RegX8632::Reg_NUM; }
Jim Stichnoth98712a32014-10-24 10:59:02 -070039 Variable *getPhysicalRegister(SizeT RegNum, Type Ty = IceType_void) override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -070040 IceString getRegName(SizeT RegNum, Type Ty) const override;
41 llvm::SmallBitVector getRegisterSet(RegSetMask Include,
42 RegSetMask Exclude) const override;
43 const llvm::SmallBitVector &getRegisterSetForType(Type Ty) const override {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070044 return TypeToRegisterSet[Ty];
45 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -070046 bool hasFramePointer() const override { return IsEbpBasedFrame; }
47 SizeT getFrameOrStackReg() const override {
Jan Voungbd385e42014-09-18 18:18:10 -070048 return IsEbpBasedFrame ? RegX8632::Reg_ebp : RegX8632::Reg_esp;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070049 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -070050 size_t typeWidthInBytesOnStack(Type Ty) const override {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070051 // Round up to the next multiple of 4 bytes. In particular, i1,
52 // i8, and i16 are rounded up to 4 bytes.
53 return (typeWidthInBytes(Ty) + 3) & ~3;
54 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -070055 void emitVariable(const Variable *Var) const override;
56 void lowerArguments() override;
57 void addProlog(CfgNode *Node) override;
58 void addEpilog(CfgNode *Node) override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070059 SizeT makeNextLabelNumber() { return NextLabelNumber++; }
60 // Ensure that a 64-bit Variable has been split into 2 32-bit
61 // Variables, creating them if necessary. This is needed for all
62 // I64 operations, and it is needed for pushing F64 arguments for
63 // function calls using the 32-bit push instruction (though the
64 // latter could be done by directly writing to the stack).
65 void split64(Variable *Var);
Matt Wala45a06232014-07-09 16:33:22 -070066 void finishArgumentLowering(Variable *Arg, Variable *FramePtr,
67 size_t BasicFrameOffset, size_t &InArgsSizeBytes);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070068 Operand *loOperand(Operand *Operand);
69 Operand *hiOperand(Operand *Operand);
Jan Voung8acded02014-09-22 18:02:25 -070070 x86::Address stackVarToAsmOperand(const Variable *Var) const;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070071
Matt Wala0a450512014-07-30 12:44:39 -070072 enum X86InstructionSet {
73 // SSE2 is the PNaCl baseline instruction set.
74 SSE2,
75 SSE4_1
76 };
77
78 X86InstructionSet getInstructionSet() const { return InstructionSet; }
79
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070080protected:
81 TargetX8632(Cfg *Func);
82
Jim Stichnothb56c8f42014-09-26 09:28:46 -070083 void postLower() override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070084
Jim Stichnothb56c8f42014-09-26 09:28:46 -070085 void lowerAlloca(const InstAlloca *Inst) override;
86 void lowerArithmetic(const InstArithmetic *Inst) override;
87 void lowerAssign(const InstAssign *Inst) override;
88 void lowerBr(const InstBr *Inst) override;
89 void lowerCall(const InstCall *Inst) override;
90 void lowerCast(const InstCast *Inst) override;
91 void lowerExtractElement(const InstExtractElement *Inst) override;
92 void lowerFcmp(const InstFcmp *Inst) override;
93 void lowerIcmp(const InstIcmp *Inst) override;
94 void lowerIntrinsicCall(const InstIntrinsicCall *Inst) override;
95 void lowerInsertElement(const InstInsertElement *Inst) override;
96 void lowerLoad(const InstLoad *Inst) override;
97 void lowerPhi(const InstPhi *Inst) override;
98 void lowerRet(const InstRet *Inst) override;
99 void lowerSelect(const InstSelect *Inst) override;
100 void lowerStore(const InstStore *Inst) override;
101 void lowerSwitch(const InstSwitch *Inst) override;
102 void lowerUnreachable(const InstUnreachable *Inst) override;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700103 void prelowerPhis() override;
104 void lowerPhiAssignments(CfgNode *Node,
105 const AssignList &Assignments) override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700106 void doAddressOptLoad() override;
107 void doAddressOptStore() override;
108 void randomlyInsertNop(float Probability) override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700109
Jan Voungc820ddf2014-07-29 14:38:51 -0700110 // Naive lowering of cmpxchg.
Jan Vounga3a01a22014-07-14 10:32:41 -0700111 void lowerAtomicCmpxchg(Variable *DestPrev, Operand *Ptr, Operand *Expected,
112 Operand *Desired);
Jan Voungc820ddf2014-07-29 14:38:51 -0700113 // Attempt a more optimized lowering of cmpxchg. Returns true if optimized.
114 bool tryOptimizedCmpxchgCmpBr(Variable *DestPrev, Operand *Ptr,
115 Operand *Expected, Operand *Desired);
Jan Voung5cd240d2014-06-25 10:36:46 -0700116 void lowerAtomicRMW(Variable *Dest, uint32_t Operation, Operand *Ptr,
117 Operand *Val);
Jan Vounge4da26f2014-07-15 17:52:39 -0700118 void lowerCountZeros(bool Cttz, Type Ty, Variable *Dest, Operand *FirstVal,
119 Operand *SecondVal);
Jan Voung5cd240d2014-06-25 10:36:46 -0700120
Jan Vounga3a01a22014-07-14 10:32:41 -0700121 typedef void (TargetX8632::*LowerBinOp)(Variable *, Operand *);
122 void expandAtomicRMWAsCmpxchg(LowerBinOp op_lo, LowerBinOp op_hi,
123 Variable *Dest, Operand *Ptr, Operand *Val);
124
Matt Walace0ca8f2014-07-24 12:34:20 -0700125 void eliminateNextVectorSextInstruction(Variable *SignExtendedResult);
126
Matt Walaafeaee42014-08-07 13:47:30 -0700127 void scalarizeArithmetic(InstArithmetic::OpKind K, Variable *Dest,
128 Operand *Src0, Operand *Src1);
129
Matt Walad4799f42014-08-14 14:24:12 -0700130 void sortByAlignment(VarList &Dest, const VarList &Source) const;
131
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700132 // Operand legalization helpers. To deal with address mode
133 // constraints, the helpers will create a new Operand and emit
134 // instructions that guarantee that the Operand kind is one of those
135 // indicated by the LegalMask (a bitmask of allowed kinds). If the
136 // input Operand is known to already meet the constraints, it may be
137 // simply returned as the result, without creating any new
138 // instructions or operands.
139 enum OperandLegalization {
140 Legal_None = 0,
141 Legal_Reg = 1 << 0, // physical register, not stack location
142 Legal_Imm = 1 << 1,
143 Legal_Mem = 1 << 2, // includes [eax+4*ecx] as well as [esp+12]
144 Legal_All = ~Legal_None
145 };
146 typedef uint32_t LegalMask;
Jim Stichnothdd165072014-11-02 09:41:45 -0800147 Operand *legalize(Operand *From, LegalMask Allowed = Legal_All,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700148 int32_t RegNum = Variable::NoRegister);
Jim Stichnothad403532014-09-25 12:44:17 -0700149 Variable *legalizeToVar(Operand *From, int32_t RegNum = Variable::NoRegister);
Jan Voung5cd240d2014-06-25 10:36:46 -0700150 // Turn a pointer operand into a memory operand that can be
151 // used by a real load/store operation. Legalizes the operand as well.
152 // This is a nop if the operand is already a legal memory operand.
153 OperandX8632Mem *FormMemoryOperand(Operand *Ptr, Type Ty);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700154
155 Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister);
Jan Voung261cae32015-02-01 10:31:03 -0800156 // Make a call to an external helper function.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700157 InstCall *makeHelperCall(const IceString &Name, Variable *Dest,
158 SizeT MaxSrcs) {
Jim Stichnothd2cb4362014-11-20 11:24:42 -0800159 const bool HasTailCall = false;
Jan Voung261cae32015-02-01 10:31:03 -0800160 Constant *CallTarget = Ctx->getConstantExternSym(Name);
Jim Stichnothd2cb4362014-11-20 11:24:42 -0800161 InstCall *Call =
162 InstCall::create(Func, MaxSrcs, Dest, CallTarget, HasTailCall);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700163 return Call;
164 }
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700165 static Type stackSlotType();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700166
Matt Wala928f1292014-07-07 16:50:46 -0700167 Variable *copyToReg(Operand *Src, int32_t RegNum = Variable::NoRegister);
168
Matt Wala83b80362014-07-16 10:21:30 -0700169 // Returns a vector in a register with the given constant entries.
170 Variable *makeVectorOfZeros(Type Ty, int32_t RegNum = Variable::NoRegister);
171 Variable *makeVectorOfOnes(Type Ty, int32_t RegNum = Variable::NoRegister);
Matt Wala9a0168a2014-07-23 14:56:10 -0700172 Variable *makeVectorOfMinusOnes(Type Ty,
173 int32_t RegNum = Variable::NoRegister);
174 Variable *makeVectorOfHighOrderBits(Type Ty,
175 int32_t RegNum = Variable::NoRegister);
Matt Wala83b80362014-07-16 10:21:30 -0700176
Matt Wala49889232014-07-18 12:45:09 -0700177 // Return a memory operand corresponding to a stack allocated Variable.
178 OperandX8632Mem *getMemoryOperandForStackSlot(Type Ty, Variable *Slot,
179 uint32_t Offset = 0);
180
Jim Stichnothe6d24782014-12-19 05:42:24 -0800181 void makeRandomRegisterPermutation(
182 llvm::SmallVectorImpl<int32_t> &Permutation,
Jan Voung3ce1a992015-02-03 08:27:44 -0800183 const llvm::SmallBitVector &ExcludeRegisters) const override;
Jim Stichnothe6d24782014-12-19 05:42:24 -0800184
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)));
Jim Stichnoth47752552014-10-13 17:15:08 -0700252 _set_dest_nonkillable();
Jan Vounga3a01a22014-07-14 10:32:41 -0700253 }
Jan Voung03532e52014-09-23 13:32:18 -0700254 void _cmpxchg8b(OperandX8632Mem *Addr, Variable *Edx, Variable *Eax,
Jan Vounga3a01a22014-07-14 10:32:41 -0700255 Variable *Ecx, Variable *Ebx, bool Locked) {
256 Context.insert(
257 InstX8632Cmpxchg8b::create(Func, Addr, Edx, Eax, Ecx, Ebx, Locked));
258 // Mark edx, and eax as possibly modified by cmpxchg8b.
259 Context.insert(InstFakeDef::create(Func, Edx));
Jim Stichnoth47752552014-10-13 17:15:08 -0700260 _set_dest_nonkillable();
Jan Vounga3a01a22014-07-14 10:32:41 -0700261 Context.insert(InstFakeDef::create(Func, Eax));
Jim Stichnoth47752552014-10-13 17:15:08 -0700262 _set_dest_nonkillable();
Jan Vounga3a01a22014-07-14 10:32:41 -0700263 }
Jan Voung699bf022014-10-08 13:52:10 -0700264 void _cvt(Variable *Dest, Operand *Src0, InstX8632Cvt::CvtVariant Variant) {
265 Context.insert(InstX8632Cvt::create(Func, Dest, Src0, Variant));
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700266 }
267 void _div(Variable *Dest, Operand *Src0, Operand *Src1) {
268 Context.insert(InstX8632Div::create(Func, Dest, Src0, Src1));
269 }
Matt Wala8d1072e2014-07-11 15:43:51 -0700270 void _divps(Variable *Dest, Operand *Src0) {
271 Context.insert(InstX8632Divps::create(Func, Dest, Src0));
272 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700273 void _divss(Variable *Dest, Operand *Src0) {
274 Context.insert(InstX8632Divss::create(Func, Dest, Src0));
275 }
276 void _fld(Operand *Src0) { Context.insert(InstX8632Fld::create(Func, Src0)); }
277 void _fstp(Variable *Dest) {
278 Context.insert(InstX8632Fstp::create(Func, Dest));
279 }
280 void _idiv(Variable *Dest, Operand *Src0, Operand *Src1) {
281 Context.insert(InstX8632Idiv::create(Func, Dest, Src0, Src1));
282 }
283 void _imul(Variable *Dest, Operand *Src0) {
284 Context.insert(InstX8632Imul::create(Func, Dest, Src0));
285 }
Matt Wala0a450512014-07-30 12:44:39 -0700286 void _insertps(Variable *Dest, Operand *Src0, Operand *Src1) {
287 Context.insert(InstX8632Insertps::create(Func, Dest, Src0, Src1));
288 }
Matt Wala49889232014-07-18 12:45:09 -0700289 void _lea(Variable *Dest, Operand *Src0) {
290 Context.insert(InstX8632Lea::create(Func, Dest, Src0));
291 }
Jan Voung5cd240d2014-06-25 10:36:46 -0700292 void _mfence() { Context.insert(InstX8632Mfence::create(Func)); }
Jim Stichnothae953202014-12-20 06:17:49 -0800293 // If Dest=nullptr is passed in, then a new variable is created,
294 // marked as infinite register allocation weight, and returned
295 // through the in/out Dest argument.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700296 void _mov(Variable *&Dest, Operand *Src0,
297 int32_t RegNum = Variable::NoRegister) {
Jim Stichnothae953202014-12-20 06:17:49 -0800298 if (Dest == nullptr)
Jim Stichnothad403532014-09-25 12:44:17 -0700299 Dest = makeReg(Src0->getType(), RegNum);
300 Context.insert(InstX8632Mov::create(Func, Dest, Src0));
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700301 }
Jim Stichnoth47752552014-10-13 17:15:08 -0700302 void _mov_nonkillable(Variable *Dest, Operand *Src0) {
303 Inst *NewInst = InstX8632Mov::create(Func, Dest, Src0);
304 NewInst->setDestNonKillable();
305 Context.insert(NewInst);
306 }
Matt Wala49889232014-07-18 12:45:09 -0700307 void _movd(Variable *Dest, Operand *Src0) {
308 Context.insert(InstX8632Movd::create(Func, Dest, Src0));
309 }
Matt Wala928f1292014-07-07 16:50:46 -0700310 void _movp(Variable *Dest, Operand *Src0) {
311 Context.insert(InstX8632Movp::create(Func, Dest, Src0));
312 }
Jan Voung5cd240d2014-06-25 10:36:46 -0700313 void _movq(Variable *Dest, Operand *Src0) {
314 Context.insert(InstX8632Movq::create(Func, Dest, Src0));
315 }
Jan Vounge4dc61b2014-10-06 08:53:52 -0700316 void _movss(Variable *Dest, Variable *Src0) {
317 Context.insert(InstX8632MovssRegs::create(Func, Dest, Src0));
Matt Wala49889232014-07-18 12:45:09 -0700318 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700319 void _movsx(Variable *Dest, Operand *Src0) {
320 Context.insert(InstX8632Movsx::create(Func, Dest, Src0));
321 }
322 void _movzx(Variable *Dest, Operand *Src0) {
323 Context.insert(InstX8632Movzx::create(Func, Dest, Src0));
324 }
325 void _mul(Variable *Dest, Variable *Src0, Operand *Src1) {
326 Context.insert(InstX8632Mul::create(Func, Dest, Src0, Src1));
327 }
Matt Wala8d1072e2014-07-11 15:43:51 -0700328 void _mulps(Variable *Dest, Operand *Src0) {
329 Context.insert(InstX8632Mulps::create(Func, Dest, Src0));
330 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700331 void _mulss(Variable *Dest, Operand *Src0) {
332 Context.insert(InstX8632Mulss::create(Func, Dest, Src0));
333 }
Jan Vounga3a01a22014-07-14 10:32:41 -0700334 void _neg(Variable *SrcDest) {
335 Context.insert(InstX8632Neg::create(Func, SrcDest));
336 }
Matt Walac3302742014-08-15 16:21:56 -0700337 void _nop(SizeT Variant) {
338 Context.insert(InstX8632Nop::create(Func, Variant));
339 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700340 void _or(Variable *Dest, Operand *Src0) {
341 Context.insert(InstX8632Or::create(Func, Dest, Src0));
342 }
Matt Wala7fa22d82014-07-17 12:41:31 -0700343 void _padd(Variable *Dest, Operand *Src0) {
344 Context.insert(InstX8632Padd::create(Func, Dest, Src0));
345 }
Matt Wala83b80362014-07-16 10:21:30 -0700346 void _pand(Variable *Dest, Operand *Src0) {
347 Context.insert(InstX8632Pand::create(Func, Dest, Src0));
348 }
Matt Wala9cb61e22014-07-24 09:44:42 -0700349 void _pandn(Variable *Dest, Operand *Src0) {
350 Context.insert(InstX8632Pandn::create(Func, Dest, Src0));
351 }
Matt Wala0a450512014-07-30 12:44:39 -0700352 void _pblendvb(Variable *Dest, Operand *Src0, Operand *Src1) {
353 Context.insert(InstX8632Pblendvb::create(Func, Dest, Src0, Src1));
354 }
Matt Wala83b80362014-07-16 10:21:30 -0700355 void _pcmpeq(Variable *Dest, Operand *Src0) {
356 Context.insert(InstX8632Pcmpeq::create(Func, Dest, Src0));
357 }
358 void _pcmpgt(Variable *Dest, Operand *Src0) {
359 Context.insert(InstX8632Pcmpgt::create(Func, Dest, Src0));
360 }
Matt Wala0a450512014-07-30 12:44:39 -0700361 void _pextr(Variable *Dest, Operand *Src0, Operand *Src1) {
362 Context.insert(InstX8632Pextr::create(Func, Dest, Src0, Src1));
Matt Wala49889232014-07-18 12:45:09 -0700363 }
Matt Wala0a450512014-07-30 12:44:39 -0700364 void _pinsr(Variable *Dest, Operand *Src0, Operand *Src1) {
365 Context.insert(InstX8632Pinsr::create(Func, Dest, Src0, Src1));
Matt Wala49889232014-07-18 12:45:09 -0700366 }
Matt Wala0a450512014-07-30 12:44:39 -0700367 void _pmull(Variable *Dest, Operand *Src0) {
368 Context.insert(InstX8632Pmull::create(Func, Dest, Src0));
Matt Wala7fa22d82014-07-17 12:41:31 -0700369 }
370 void _pmuludq(Variable *Dest, Operand *Src0) {
371 Context.insert(InstX8632Pmuludq::create(Func, Dest, Src0));
372 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700373 void _pop(Variable *Dest) {
374 Context.insert(InstX8632Pop::create(Func, Dest));
375 }
Matt Wala7fa22d82014-07-17 12:41:31 -0700376 void _por(Variable *Dest, Operand *Src0) {
377 Context.insert(InstX8632Por::create(Func, Dest, Src0));
378 }
379 void _pshufd(Variable *Dest, Operand *Src0, Operand *Src1) {
380 Context.insert(InstX8632Pshufd::create(Func, Dest, Src0, Src1));
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700381 }
Matt Wala83b80362014-07-16 10:21:30 -0700382 void _psll(Variable *Dest, Operand *Src0) {
383 Context.insert(InstX8632Psll::create(Func, Dest, Src0));
384 }
385 void _psra(Variable *Dest, Operand *Src0) {
386 Context.insert(InstX8632Psra::create(Func, Dest, Src0));
387 }
388 void _psub(Variable *Dest, Operand *Src0) {
389 Context.insert(InstX8632Psub::create(Func, Dest, Src0));
390 }
Jan Voung0b9eee52014-10-07 11:20:10 -0700391 void _push(Variable *Src0) {
392 Context.insert(InstX8632Push::create(Func, Src0));
Matt Wala7fa22d82014-07-17 12:41:31 -0700393 }
Matt Wala8d1072e2014-07-11 15:43:51 -0700394 void _pxor(Variable *Dest, Operand *Src0) {
395 Context.insert(InstX8632Pxor::create(Func, Dest, Src0));
396 }
Jim Stichnothae953202014-12-20 06:17:49 -0800397 void _ret(Variable *Src0 = nullptr) {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700398 Context.insert(InstX8632Ret::create(Func, Src0));
399 }
Jan Voung7fa813b2014-07-18 13:01:08 -0700400 void _rol(Variable *Dest, Operand *Src0) {
401 Context.insert(InstX8632Rol::create(Func, Dest, Src0));
402 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700403 void _sar(Variable *Dest, Operand *Src0) {
404 Context.insert(InstX8632Sar::create(Func, Dest, Src0));
405 }
406 void _sbb(Variable *Dest, Operand *Src0) {
407 Context.insert(InstX8632Sbb::create(Func, Dest, Src0));
408 }
409 void _shl(Variable *Dest, Operand *Src0) {
410 Context.insert(InstX8632Shl::create(Func, Dest, Src0));
411 }
412 void _shld(Variable *Dest, Variable *Src0, Variable *Src1) {
413 Context.insert(InstX8632Shld::create(Func, Dest, Src0, Src1));
414 }
415 void _shr(Variable *Dest, Operand *Src0) {
416 Context.insert(InstX8632Shr::create(Func, Dest, Src0));
417 }
418 void _shrd(Variable *Dest, Variable *Src0, Variable *Src1) {
419 Context.insert(InstX8632Shrd::create(Func, Dest, Src0, Src1));
420 }
Matt Wala7fa22d82014-07-17 12:41:31 -0700421 void _shufps(Variable *Dest, Operand *Src0, Operand *Src1) {
422 Context.insert(InstX8632Shufps::create(Func, Dest, Src0, Src1));
423 }
Jan Voungf37fbbe2014-07-09 16:13:13 -0700424 void _sqrtss(Variable *Dest, Operand *Src0) {
425 Context.insert(InstX8632Sqrtss::create(Func, Dest, Src0));
426 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700427 void _store(Operand *Value, OperandX8632 *Mem) {
428 Context.insert(InstX8632Store::create(Func, Value, Mem));
429 }
Jan Vounge4dc61b2014-10-06 08:53:52 -0700430 void _storep(Variable *Value, OperandX8632Mem *Mem) {
Matt Wala105b7042014-08-11 19:56:19 -0700431 Context.insert(InstX8632StoreP::create(Func, Value, Mem));
432 }
Jan Vounge4dc61b2014-10-06 08:53:52 -0700433 void _storeq(Variable *Value, OperandX8632Mem *Mem) {
Jan Voung5cd240d2014-06-25 10:36:46 -0700434 Context.insert(InstX8632StoreQ::create(Func, Value, Mem));
435 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700436 void _sub(Variable *Dest, Operand *Src0) {
437 Context.insert(InstX8632Sub::create(Func, Dest, Src0));
438 }
Matt Wala8d1072e2014-07-11 15:43:51 -0700439 void _subps(Variable *Dest, Operand *Src0) {
440 Context.insert(InstX8632Subps::create(Func, Dest, Src0));
441 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700442 void _subss(Variable *Dest, Operand *Src0) {
443 Context.insert(InstX8632Subss::create(Func, Dest, Src0));
444 }
445 void _test(Operand *Src0, Operand *Src1) {
446 Context.insert(InstX8632Test::create(Func, Src0, Src1));
447 }
448 void _ucomiss(Operand *Src0, Operand *Src1) {
449 Context.insert(InstX8632Ucomiss::create(Func, Src0, Src1));
450 }
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700451 void _ud2() { Context.insert(InstX8632UD2::create(Func)); }
Jan Voung5cd240d2014-06-25 10:36:46 -0700452 void _xadd(Operand *Dest, Variable *Src, bool Locked) {
453 Context.insert(InstX8632Xadd::create(Func, Dest, Src, Locked));
454 // The xadd exchanges Dest and Src (modifying Src).
455 // Model that update with a FakeDef.
Jan Vounga3a01a22014-07-14 10:32:41 -0700456 Context.insert(
457 InstFakeDef::create(Func, Src, llvm::dyn_cast<Variable>(Dest)));
Jim Stichnoth47752552014-10-13 17:15:08 -0700458 _set_dest_nonkillable();
Jan Vounga3a01a22014-07-14 10:32:41 -0700459 }
460 void _xchg(Operand *Dest, Variable *Src) {
461 Context.insert(InstX8632Xchg::create(Func, Dest, Src));
462 // The xchg modifies Dest and Src -- model that update with a FakeDef.
463 Context.insert(
464 InstFakeDef::create(Func, Src, llvm::dyn_cast<Variable>(Dest)));
Jim Stichnoth47752552014-10-13 17:15:08 -0700465 _set_dest_nonkillable();
Jan Voung5cd240d2014-06-25 10:36:46 -0700466 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700467 void _xor(Variable *Dest, Operand *Src0) {
468 Context.insert(InstX8632Xor::create(Func, Dest, Src0));
469 }
Jim Stichnoth47752552014-10-13 17:15:08 -0700470 void _set_dest_nonkillable() {
471 Context.getLastInserted()->setDestNonKillable();
472 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700473
Matt Wala0a450512014-07-30 12:44:39 -0700474 const X86InstructionSet InstructionSet;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700475 bool IsEbpBasedFrame;
Matt Wala105b7042014-08-11 19:56:19 -0700476 bool NeedsStackAlignment;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700477 size_t FrameSizeLocals;
Matt Walad4799f42014-08-14 14:24:12 -0700478 size_t SpillAreaSizeBytes;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700479 llvm::SmallBitVector TypeToRegisterSet[IceType_NUM];
480 llvm::SmallBitVector ScratchRegs;
481 llvm::SmallBitVector RegsUsed;
482 SizeT NextLabelNumber;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700483 VarList PhysicalRegisters[IceType_NUM];
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700484 static IceString RegNames[];
485
486private:
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700487 ~TargetX8632() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700488};
489
Jan Voung72984d82015-01-29 14:42:38 -0800490class TargetDataX8632 : public TargetDataLowering {
491 TargetDataX8632() = delete;
492 TargetDataX8632(const TargetDataX8632 &) = delete;
493 TargetDataX8632 &operator=(const TargetDataX8632 &) = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700494
Jim Stichnothde4ca712014-06-29 08:13:48 -0700495public:
Jan Voung72984d82015-01-29 14:42:38 -0800496 static TargetDataLowering *create(GlobalContext *Ctx) {
497 return new TargetDataX8632(Ctx);
Jim Stichnothde4ca712014-06-29 08:13:48 -0700498 }
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700499
Jan Voung72984d82015-01-29 14:42:38 -0800500 void lowerGlobal(const VariableDeclaration &Var) const final;
501 void lowerGlobalsELF(const VariableDeclarationList &Vars) const final;
502 void lowerConstants(GlobalContext *Ctx) const final;
Jim Stichnothde4ca712014-06-29 08:13:48 -0700503
504protected:
Jan Voung72984d82015-01-29 14:42:38 -0800505 TargetDataX8632(GlobalContext *Ctx);
Jim Stichnothde4ca712014-06-29 08:13:48 -0700506
507private:
Jan Voung72984d82015-01-29 14:42:38 -0800508 ~TargetDataX8632() override {}
Jim Stichnothfa4efea2015-01-27 05:06:03 -0800509 template <typename T> static void emitConstantPool(GlobalContext *Ctx);
Jim Stichnothde4ca712014-06-29 08:13:48 -0700510};
511
Jan Voungbc004632014-09-16 15:09:10 -0700512template <> void ConstantInteger32::emit(GlobalContext *Ctx) const;
513template <> void ConstantInteger64::emit(GlobalContext *Ctx) const;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700514template <> void ConstantFloat::emit(GlobalContext *Ctx) const;
515template <> void ConstantDouble::emit(GlobalContext *Ctx) const;
Jim Stichnothf61d5b22014-05-23 13:31:24 -0700516
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700517} // end of namespace Ice
518
519#endif // SUBZERO_SRC_ICETARGETLOWERINGX8632_H