OLD | NEW |
---|---|
(Empty) | |
1 //===- 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 | |
23 namespace Ice { | |
24 | |
25 class TargetX8632 : public TargetLowering { | |
26 public: | |
27 static TargetX8632 *create(Cfg *Func) { return new TargetX8632(Func); } | |
28 | |
29 virtual void translateOm1(); | |
30 | |
31 virtual Variable *getPhysicalRegister(SizeT RegNum); | |
32 virtual IceString getRegName(SizeT RegNum, Type Ty) const; | |
33 virtual llvm::SmallBitVector getRegisterSet(RegSetMask Include, | |
34 RegSetMask Exclude) const; | |
35 virtual const llvm::SmallBitVector &getRegisterSetForType(Type Ty) const { | |
36 return TypeToRegisterSet[Ty]; | |
37 } | |
38 virtual bool hasFramePointer() const { return IsEbpBasedFrame; } | |
39 virtual SizeT getFrameOrStackReg() const { | |
40 return IsEbpBasedFrame ? Reg_ebp : Reg_esp; | |
41 } | |
42 virtual size_t typeWidthInBytesOnStack(Type Ty) { | |
43 // Round up to the next multiple of 4 bytes. In particular, i1, | |
44 // i8, and i16 are rounded up to 4 bytes. | |
45 return (typeWidthInBytes(Ty) + 3) & ~3; | |
46 } | |
47 virtual void emitVariable(const Variable *Var, const Cfg *Func) const; | |
48 virtual void addProlog(CfgNode *Node); | |
49 virtual void addEpilog(CfgNode *Node); | |
50 SizeT makeNextLabelNumber() { return NextLabelNumber++; } | |
51 // Ensure that a 64-bit Variable has been split into 2 32-bit | |
52 // Variables, creating them if necessary. This is needed for all | |
53 // I64 operations, and it is needed for pushing F64 arguments for | |
54 // function calls using the 32-bit push instruction (though the | |
55 // latter could be done by directly writing to the stack). | |
56 void split64(Variable *Var); | |
57 void setArgOffsetAndCopy(Variable *Arg, Variable *FramePtr, | |
58 int32_t BasicFrameOffset, int32_t &InArgsSizeBytes); | |
59 Operand *loOperand(Operand *Operand); | |
60 Operand *hiOperand(Operand *Operand); | |
61 | |
62 enum Registers { | |
63 #define X(val, init, name, name16, name8, scratch, preserved, stackptr, \ | |
64 frameptr, isI8, isInt, isFP) \ | |
65 val init, | |
66 REGX8632_TABLE | |
67 #undef X | |
68 Reg_NUM | |
69 }; | |
70 | |
71 protected: | |
72 TargetX8632(Cfg *Func); | |
73 | |
74 virtual void postLower(); | |
75 | |
76 virtual void lowerAlloca(const InstAlloca *Inst); | |
77 virtual void lowerArithmetic(const InstArithmetic *Inst); | |
78 virtual void lowerAssign(const InstAssign *Inst); | |
79 virtual void lowerBr(const InstBr *Inst); | |
80 virtual void lowerCall(const InstCall *Inst); | |
81 virtual void lowerCast(const InstCast *Inst); | |
82 virtual void lowerFcmp(const InstFcmp *Inst); | |
83 virtual void lowerIcmp(const InstIcmp *Inst); | |
84 virtual void lowerLoad(const InstLoad *Inst); | |
85 virtual void lowerPhi(const InstPhi *Inst); | |
86 virtual void lowerRet(const InstRet *Inst); | |
87 virtual void lowerSelect(const InstSelect *Inst); | |
88 virtual void lowerStore(const InstStore *Inst); | |
89 virtual void lowerSwitch(const InstSwitch *Inst); | |
90 virtual void lowerUnreachable(const InstUnreachable *Inst); | |
91 | |
92 enum OperandLegalization { | |
93 Legal_None = 0, | |
94 Legal_Reg = 1 << 0, | |
95 Legal_Imm = 1 << 1, | |
96 Legal_Mem = 1 << 2, // includes [eax+4*ecx] as well as [esp+12] | |
97 Legal_All = ~Legal_None | |
98 }; | |
99 typedef uint32_t LegalMask; | |
100 Operand *legalize(Operand *From, LegalMask Allowed = Legal_All, | |
jvoung (off chromium)
2014/05/15 23:47:34
Does it make sense to leave a comment for the lega
Jim Stichnoth
2014/05/17 14:14:32
Yeah, that's a good idea. I left a comment here,
| |
101 bool AllowOverlap = false, | |
102 int32_t RegNum = Variable::NoRegister); | |
103 Variable *legalizeToVar(Operand *From, bool AllowOverlap = false, | |
104 int32_t RegNum = Variable::NoRegister); | |
105 Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister); | |
106 InstCall *makeHelperCall(const IceString &Name, Variable *Dest, | |
107 SizeT MaxSrcs) { | |
108 bool SuppressMangling = true; | |
109 Type Ty = Dest ? Dest->getType() : IceType_void; | |
110 Constant *CallTarget = Ctx->getConstantSym(Ty, 0, Name, SuppressMangling); | |
111 InstCall *Call = InstCall::create(Func, MaxSrcs, Dest, CallTarget); | |
112 return Call; | |
113 } | |
114 | |
115 // The following are helpers that insert lowered x86 instructions | |
116 // with minimal syntactic overhead, so that the lowering code can | |
117 // look as close to assembly as practical. | |
118 void _adc(Variable *Dest, Operand *Src0) { | |
119 Context.insert(InstX8632Adc::create(Func, Dest, Src0)); | |
120 } | |
121 void _add(Variable *Dest, Operand *Src0) { | |
122 Context.insert(InstX8632Add::create(Func, Dest, Src0)); | |
123 } | |
124 void _addss(Variable *Dest, Operand *Src0) { | |
125 Context.insert(InstX8632Addss::create(Func, Dest, Src0)); | |
126 } | |
127 void _and(Variable *Dest, Operand *Src0) { | |
128 Context.insert(InstX8632And::create(Func, Dest, Src0)); | |
129 } | |
130 void _br(InstX8632Br::BrCond Condition, CfgNode *TargetTrue, | |
131 CfgNode *TargetFalse) { | |
132 Context.insert( | |
133 InstX8632Br::create(Func, TargetTrue, TargetFalse, Condition)); | |
134 } | |
135 void _br(CfgNode *Target) { | |
136 Context.insert(InstX8632Br::create(Func, Target)); | |
137 } | |
138 void _br(InstX8632Br::BrCond Condition, CfgNode *Target) { | |
139 Context.insert(InstX8632Br::create(Func, Target, Condition)); | |
140 } | |
141 void _br(InstX8632Br::BrCond Condition, InstX8632Label *Label) { | |
142 Context.insert(InstX8632Br::create(Func, Label, Condition)); | |
143 } | |
144 void _cdq(Variable *Dest, Operand *Src0) { | |
145 Context.insert(InstX8632Cdq::create(Func, Dest, Src0)); | |
146 } | |
147 void _cmp(Operand *Src0, Operand *Src1) { | |
148 Context.insert(InstX8632Icmp::create(Func, Src0, Src1)); | |
149 } | |
150 void _cvt(Variable *Dest, Operand *Src0) { | |
151 Context.insert(InstX8632Cvt::create(Func, Dest, Src0)); | |
152 } | |
153 void _div(Variable *Dest, Operand *Src0, Operand *Src1) { | |
154 Context.insert(InstX8632Div::create(Func, Dest, Src0, Src1)); | |
155 } | |
156 void _divss(Variable *Dest, Operand *Src0) { | |
157 Context.insert(InstX8632Divss::create(Func, Dest, Src0)); | |
158 } | |
159 void _fld(Operand *Src0) { Context.insert(InstX8632Fld::create(Func, Src0)); } | |
160 void _fstp(Variable *Dest) { | |
161 Context.insert(InstX8632Fstp::create(Func, Dest)); | |
162 } | |
163 void _idiv(Variable *Dest, Operand *Src0, Operand *Src1) { | |
164 Context.insert(InstX8632Idiv::create(Func, Dest, Src0, Src1)); | |
165 } | |
166 void _imul(Variable *Dest, Operand *Src0) { | |
167 Context.insert(InstX8632Imul::create(Func, Dest, Src0)); | |
168 } | |
169 // If Dest=NULL is passed in, then a new variable is created, marked | |
170 // as infinite register allocation weight, and returned through the | |
171 // in/out Dest argument. | |
172 void _mov(Variable *&Dest, Operand *Src0, | |
173 int32_t RegNum = Variable::NoRegister) { | |
174 if (Dest == NULL) { | |
175 Dest = legalizeToVar(Src0, false, RegNum); | |
176 } else { | |
177 Context.insert(InstX8632Mov::create(Func, Dest, Src0)); | |
178 } | |
179 } | |
180 void _movsx(Variable *Dest, Operand *Src0) { | |
181 Context.insert(InstX8632Movsx::create(Func, Dest, Src0)); | |
182 } | |
183 void _movzx(Variable *Dest, Operand *Src0) { | |
184 Context.insert(InstX8632Movzx::create(Func, Dest, Src0)); | |
185 } | |
186 void _mul(Variable *Dest, Variable *Src0, Operand *Src1) { | |
187 Context.insert(InstX8632Mul::create(Func, Dest, Src0, Src1)); | |
188 } | |
189 void _mulss(Variable *Dest, Operand *Src0) { | |
190 Context.insert(InstX8632Mulss::create(Func, Dest, Src0)); | |
191 } | |
192 void _or(Variable *Dest, Operand *Src0) { | |
193 Context.insert(InstX8632Or::create(Func, Dest, Src0)); | |
194 } | |
195 void _pop(Variable *Dest) { | |
196 Context.insert(InstX8632Pop::create(Func, Dest)); | |
197 } | |
198 void _push(Operand *Src0, bool SuppressStackAdjustment = false) { | |
199 Context.insert(InstX8632Push::create(Func, Src0, SuppressStackAdjustment)); | |
200 } | |
201 void _ret(Variable *Src0 = NULL) { | |
202 Context.insert(InstX8632Ret::create(Func, Src0)); | |
203 } | |
204 void _sar(Variable *Dest, Operand *Src0) { | |
205 Context.insert(InstX8632Sar::create(Func, Dest, Src0)); | |
206 } | |
207 void _sbb(Variable *Dest, Operand *Src0) { | |
208 Context.insert(InstX8632Sbb::create(Func, Dest, Src0)); | |
209 } | |
210 void _shl(Variable *Dest, Operand *Src0) { | |
211 Context.insert(InstX8632Shl::create(Func, Dest, Src0)); | |
212 } | |
213 void _shld(Variable *Dest, Variable *Src0, Variable *Src1) { | |
214 Context.insert(InstX8632Shld::create(Func, Dest, Src0, Src1)); | |
215 } | |
216 void _shr(Variable *Dest, Operand *Src0) { | |
217 Context.insert(InstX8632Shr::create(Func, Dest, Src0)); | |
218 } | |
219 void _shrd(Variable *Dest, Variable *Src0, Variable *Src1) { | |
220 Context.insert(InstX8632Shrd::create(Func, Dest, Src0, Src1)); | |
221 } | |
222 void _store(Operand *Value, OperandX8632 *Mem) { | |
223 Context.insert(InstX8632Store::create(Func, Value, Mem)); | |
224 } | |
225 void _sub(Variable *Dest, Operand *Src0) { | |
226 Context.insert(InstX8632Sub::create(Func, Dest, Src0)); | |
227 } | |
228 void _subss(Variable *Dest, Operand *Src0) { | |
229 Context.insert(InstX8632Subss::create(Func, Dest, Src0)); | |
230 } | |
231 void _test(Operand *Src0, Operand *Src1) { | |
232 Context.insert(InstX8632Test::create(Func, Src0, Src1)); | |
233 } | |
234 void _ucomiss(Operand *Src0, Operand *Src1) { | |
235 Context.insert(InstX8632Ucomiss::create(Func, Src0, Src1)); | |
236 } | |
237 void _xor(Variable *Dest, Operand *Src0) { | |
238 Context.insert(InstX8632Xor::create(Func, Dest, Src0)); | |
239 } | |
240 | |
241 bool IsEbpBasedFrame; | |
242 int32_t FrameSizeLocals; | |
243 int32_t LocalsSizeBytes; | |
244 llvm::SmallBitVector TypeToRegisterSet[IceType_NUM]; | |
245 llvm::SmallBitVector ScratchRegs; | |
246 llvm::SmallBitVector RegsUsed; | |
247 SizeT NextLabelNumber; | |
248 bool ComputedLiveRanges; | |
249 VarList PhysicalRegisters; | |
250 static IceString RegNames[]; | |
251 | |
252 private: | |
253 TargetX8632(const TargetX8632 &) LLVM_DELETED_FUNCTION; | |
254 TargetX8632 &operator=(const TargetX8632 &) LLVM_DELETED_FUNCTION; | |
255 virtual ~TargetX8632() {} | |
256 }; | |
257 | |
258 } // end of namespace Ice | |
259 | |
260 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8632_H | |
OLD | NEW |