OLD | NEW |
1 //===- subzero/src/IceTargetLoweringX8632.h - x86-32 lowering ---*- C++ -*-===// | 1 //===- subzero/src/IceTargetLoweringX8632.h - x86-32 lowering ---*- C++ -*-===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file declares the TargetLoweringX8632 class, which | 10 // This file declares the TargetLoweringX8632 class, which |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 virtual void lowerLoad(const InstLoad *Inst); | 87 virtual void lowerLoad(const InstLoad *Inst); |
88 virtual void lowerPhi(const InstPhi *Inst); | 88 virtual void lowerPhi(const InstPhi *Inst); |
89 virtual void lowerRet(const InstRet *Inst); | 89 virtual void lowerRet(const InstRet *Inst); |
90 virtual void lowerSelect(const InstSelect *Inst); | 90 virtual void lowerSelect(const InstSelect *Inst); |
91 virtual void lowerStore(const InstStore *Inst); | 91 virtual void lowerStore(const InstStore *Inst); |
92 virtual void lowerSwitch(const InstSwitch *Inst); | 92 virtual void lowerSwitch(const InstSwitch *Inst); |
93 virtual void lowerUnreachable(const InstUnreachable *Inst); | 93 virtual void lowerUnreachable(const InstUnreachable *Inst); |
94 virtual void doAddressOptLoad(); | 94 virtual void doAddressOptLoad(); |
95 virtual void doAddressOptStore(); | 95 virtual void doAddressOptStore(); |
96 | 96 |
| 97 void lowerAtomicRMW(Variable *Dest, uint32_t Operation, Operand *Ptr, |
| 98 Operand *Val); |
| 99 |
97 // Operand legalization helpers. To deal with address mode | 100 // Operand legalization helpers. To deal with address mode |
98 // constraints, the helpers will create a new Operand and emit | 101 // constraints, the helpers will create a new Operand and emit |
99 // instructions that guarantee that the Operand kind is one of those | 102 // instructions that guarantee that the Operand kind is one of those |
100 // indicated by the LegalMask (a bitmask of allowed kinds). If the | 103 // indicated by the LegalMask (a bitmask of allowed kinds). If the |
101 // input Operand is known to already meet the constraints, it may be | 104 // input Operand is known to already meet the constraints, it may be |
102 // simply returned as the result, without creating any new | 105 // simply returned as the result, without creating any new |
103 // instructions or operands. | 106 // instructions or operands. |
104 enum OperandLegalization { | 107 enum OperandLegalization { |
105 Legal_None = 0, | 108 Legal_None = 0, |
106 Legal_Reg = 1 << 0, // physical register, not stack location | 109 Legal_Reg = 1 << 0, // physical register, not stack location |
107 Legal_Imm = 1 << 1, | 110 Legal_Imm = 1 << 1, |
108 Legal_Mem = 1 << 2, // includes [eax+4*ecx] as well as [esp+12] | 111 Legal_Mem = 1 << 2, // includes [eax+4*ecx] as well as [esp+12] |
109 Legal_All = ~Legal_None | 112 Legal_All = ~Legal_None |
110 }; | 113 }; |
111 typedef uint32_t LegalMask; | 114 typedef uint32_t LegalMask; |
112 Operand *legalize(Operand *From, LegalMask Allowed = Legal_All, | 115 Operand *legalize(Operand *From, LegalMask Allowed = Legal_All, |
113 bool AllowOverlap = false, | 116 bool AllowOverlap = false, |
114 int32_t RegNum = Variable::NoRegister); | 117 int32_t RegNum = Variable::NoRegister); |
115 Variable *legalizeToVar(Operand *From, bool AllowOverlap = false, | 118 Variable *legalizeToVar(Operand *From, bool AllowOverlap = false, |
116 int32_t RegNum = Variable::NoRegister); | 119 int32_t RegNum = Variable::NoRegister); |
| 120 // Turn a pointer operand into a memory operand that can be |
| 121 // used by a real load/store operation. Legalizes the operand as well. |
| 122 // This is a nop if the operand is already a legal memory operand. |
| 123 OperandX8632Mem *FormMemoryOperand(Operand *Ptr, Type Ty); |
117 | 124 |
118 Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister); | 125 Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister); |
119 InstCall *makeHelperCall(const IceString &Name, Variable *Dest, | 126 InstCall *makeHelperCall(const IceString &Name, Variable *Dest, |
120 SizeT MaxSrcs) { | 127 SizeT MaxSrcs) { |
121 bool SuppressMangling = true; | 128 bool SuppressMangling = true; |
122 Type Ty = Dest ? Dest->getType() : IceType_void; | 129 Type Ty = Dest ? Dest->getType() : IceType_void; |
123 Constant *CallTarget = Ctx->getConstantSym(Ty, 0, Name, SuppressMangling); | 130 Constant *CallTarget = Ctx->getConstantSym(Ty, 0, Name, SuppressMangling); |
124 InstCall *Call = InstCall::create(Func, MaxSrcs, Dest, CallTarget); | 131 InstCall *Call = InstCall::create(Func, MaxSrcs, Dest, CallTarget); |
125 return Call; | 132 return Call; |
126 } | 133 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 void _fld(Operand *Src0) { Context.insert(InstX8632Fld::create(Func, Src0)); } | 180 void _fld(Operand *Src0) { Context.insert(InstX8632Fld::create(Func, Src0)); } |
174 void _fstp(Variable *Dest) { | 181 void _fstp(Variable *Dest) { |
175 Context.insert(InstX8632Fstp::create(Func, Dest)); | 182 Context.insert(InstX8632Fstp::create(Func, Dest)); |
176 } | 183 } |
177 void _idiv(Variable *Dest, Operand *Src0, Operand *Src1) { | 184 void _idiv(Variable *Dest, Operand *Src0, Operand *Src1) { |
178 Context.insert(InstX8632Idiv::create(Func, Dest, Src0, Src1)); | 185 Context.insert(InstX8632Idiv::create(Func, Dest, Src0, Src1)); |
179 } | 186 } |
180 void _imul(Variable *Dest, Operand *Src0) { | 187 void _imul(Variable *Dest, Operand *Src0) { |
181 Context.insert(InstX8632Imul::create(Func, Dest, Src0)); | 188 Context.insert(InstX8632Imul::create(Func, Dest, Src0)); |
182 } | 189 } |
| 190 void _mfence() { Context.insert(InstX8632Mfence::create(Func)); } |
183 // If Dest=NULL is passed in, then a new variable is created, marked | 191 // If Dest=NULL is passed in, then a new variable is created, marked |
184 // as infinite register allocation weight, and returned through the | 192 // as infinite register allocation weight, and returned through the |
185 // in/out Dest argument. | 193 // in/out Dest argument. |
186 void _mov(Variable *&Dest, Operand *Src0, | 194 void _mov(Variable *&Dest, Operand *Src0, |
187 int32_t RegNum = Variable::NoRegister) { | 195 int32_t RegNum = Variable::NoRegister) { |
188 if (Dest == NULL) { | 196 if (Dest == NULL) { |
189 Dest = legalizeToVar(Src0, false, RegNum); | 197 Dest = legalizeToVar(Src0, false, RegNum); |
190 } else { | 198 } else { |
191 Context.insert(InstX8632Mov::create(Func, Dest, Src0)); | 199 Context.insert(InstX8632Mov::create(Func, Dest, Src0)); |
192 } | 200 } |
193 } | 201 } |
| 202 void _movq(Variable *Dest, Operand *Src0) { |
| 203 Context.insert(InstX8632Movq::create(Func, Dest, Src0)); |
| 204 } |
194 void _movsx(Variable *Dest, Operand *Src0) { | 205 void _movsx(Variable *Dest, Operand *Src0) { |
195 Context.insert(InstX8632Movsx::create(Func, Dest, Src0)); | 206 Context.insert(InstX8632Movsx::create(Func, Dest, Src0)); |
196 } | 207 } |
197 void _movzx(Variable *Dest, Operand *Src0) { | 208 void _movzx(Variable *Dest, Operand *Src0) { |
198 Context.insert(InstX8632Movzx::create(Func, Dest, Src0)); | 209 Context.insert(InstX8632Movzx::create(Func, Dest, Src0)); |
199 } | 210 } |
200 void _mul(Variable *Dest, Variable *Src0, Operand *Src1) { | 211 void _mul(Variable *Dest, Variable *Src0, Operand *Src1) { |
201 Context.insert(InstX8632Mul::create(Func, Dest, Src0, Src1)); | 212 Context.insert(InstX8632Mul::create(Func, Dest, Src0, Src1)); |
202 } | 213 } |
203 void _mulss(Variable *Dest, Operand *Src0) { | 214 void _mulss(Variable *Dest, Operand *Src0) { |
(...skipping 25 matching lines...) Expand all Loading... |
229 } | 240 } |
230 void _shr(Variable *Dest, Operand *Src0) { | 241 void _shr(Variable *Dest, Operand *Src0) { |
231 Context.insert(InstX8632Shr::create(Func, Dest, Src0)); | 242 Context.insert(InstX8632Shr::create(Func, Dest, Src0)); |
232 } | 243 } |
233 void _shrd(Variable *Dest, Variable *Src0, Variable *Src1) { | 244 void _shrd(Variable *Dest, Variable *Src0, Variable *Src1) { |
234 Context.insert(InstX8632Shrd::create(Func, Dest, Src0, Src1)); | 245 Context.insert(InstX8632Shrd::create(Func, Dest, Src0, Src1)); |
235 } | 246 } |
236 void _store(Operand *Value, OperandX8632 *Mem) { | 247 void _store(Operand *Value, OperandX8632 *Mem) { |
237 Context.insert(InstX8632Store::create(Func, Value, Mem)); | 248 Context.insert(InstX8632Store::create(Func, Value, Mem)); |
238 } | 249 } |
| 250 void _storeq(Operand *Value, OperandX8632 *Mem) { |
| 251 Context.insert(InstX8632StoreQ::create(Func, Value, Mem)); |
| 252 } |
239 void _sub(Variable *Dest, Operand *Src0) { | 253 void _sub(Variable *Dest, Operand *Src0) { |
240 Context.insert(InstX8632Sub::create(Func, Dest, Src0)); | 254 Context.insert(InstX8632Sub::create(Func, Dest, Src0)); |
241 } | 255 } |
242 void _subss(Variable *Dest, Operand *Src0) { | 256 void _subss(Variable *Dest, Operand *Src0) { |
243 Context.insert(InstX8632Subss::create(Func, Dest, Src0)); | 257 Context.insert(InstX8632Subss::create(Func, Dest, Src0)); |
244 } | 258 } |
245 void _test(Operand *Src0, Operand *Src1) { | 259 void _test(Operand *Src0, Operand *Src1) { |
246 Context.insert(InstX8632Test::create(Func, Src0, Src1)); | 260 Context.insert(InstX8632Test::create(Func, Src0, Src1)); |
247 } | 261 } |
248 void _ucomiss(Operand *Src0, Operand *Src1) { | 262 void _ucomiss(Operand *Src0, Operand *Src1) { |
249 Context.insert(InstX8632Ucomiss::create(Func, Src0, Src1)); | 263 Context.insert(InstX8632Ucomiss::create(Func, Src0, Src1)); |
250 } | 264 } |
251 void _ud2() { Context.insert(InstX8632UD2::create(Func)); } | 265 void _ud2() { Context.insert(InstX8632UD2::create(Func)); } |
| 266 void _xadd(Operand *Dest, Variable *Src, bool Locked) { |
| 267 Context.insert(InstX8632Xadd::create(Func, Dest, Src, Locked)); |
| 268 // The xadd exchanges Dest and Src (modifying Src). |
| 269 // Model that update with a FakeDef. |
| 270 Context.insert(InstFakeDef::create(Func, Src)); |
| 271 } |
252 void _xor(Variable *Dest, Operand *Src0) { | 272 void _xor(Variable *Dest, Operand *Src0) { |
253 Context.insert(InstX8632Xor::create(Func, Dest, Src0)); | 273 Context.insert(InstX8632Xor::create(Func, Dest, Src0)); |
254 } | 274 } |
255 | 275 |
256 bool IsEbpBasedFrame; | 276 bool IsEbpBasedFrame; |
257 size_t FrameSizeLocals; | 277 size_t FrameSizeLocals; |
258 size_t LocalsSizeBytes; | 278 size_t LocalsSizeBytes; |
259 llvm::SmallBitVector TypeToRegisterSet[IceType_NUM]; | 279 llvm::SmallBitVector TypeToRegisterSet[IceType_NUM]; |
260 llvm::SmallBitVector ScratchRegs; | 280 llvm::SmallBitVector ScratchRegs; |
261 llvm::SmallBitVector RegsUsed; | 281 llvm::SmallBitVector RegsUsed; |
262 SizeT NextLabelNumber; | 282 SizeT NextLabelNumber; |
263 bool ComputedLiveRanges; | 283 bool ComputedLiveRanges; |
264 VarList PhysicalRegisters; | 284 VarList PhysicalRegisters; |
265 static IceString RegNames[]; | 285 static IceString RegNames[]; |
266 | 286 |
267 private: | 287 private: |
268 TargetX8632(const TargetX8632 &) LLVM_DELETED_FUNCTION; | 288 TargetX8632(const TargetX8632 &) LLVM_DELETED_FUNCTION; |
269 TargetX8632 &operator=(const TargetX8632 &) LLVM_DELETED_FUNCTION; | 289 TargetX8632 &operator=(const TargetX8632 &) LLVM_DELETED_FUNCTION; |
270 virtual ~TargetX8632() {} | 290 virtual ~TargetX8632() {} |
271 template <typename T> void emitConstantPool() const; | 291 template <typename T> void emitConstantPool() const; |
272 }; | 292 }; |
273 | 293 |
274 template <> void ConstantFloat::emit(GlobalContext *Ctx) const; | 294 template <> void ConstantFloat::emit(GlobalContext *Ctx) const; |
275 template <> void ConstantDouble::emit(GlobalContext *Ctx) const; | 295 template <> void ConstantDouble::emit(GlobalContext *Ctx) const; |
276 | 296 |
277 } // end of namespace Ice | 297 } // end of namespace Ice |
278 | 298 |
279 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8632_H | 299 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8632_H |
OLD | NEW |