OLD | NEW |
1 //===- subzero/src/IceTargetLoweringX86Base.h - x86 lowering ----*- C++ -*-===// | 1 //===- subzero/src/IceTargetLoweringX86Base.h - x86 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 TargetLoweringX86 template class, which | 10 // This file declares the TargetLoweringX86 template class, which |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 void lowerIntrinsicCall(const InstIntrinsicCall *Inst) override; | 175 void lowerIntrinsicCall(const InstIntrinsicCall *Inst) override; |
176 void lowerInsertElement(const InstInsertElement *Inst) override; | 176 void lowerInsertElement(const InstInsertElement *Inst) override; |
177 void lowerLoad(const InstLoad *Inst) override; | 177 void lowerLoad(const InstLoad *Inst) override; |
178 void lowerPhi(const InstPhi *Inst) override; | 178 void lowerPhi(const InstPhi *Inst) override; |
179 void lowerRet(const InstRet *Inst) override; | 179 void lowerRet(const InstRet *Inst) override; |
180 void lowerSelect(const InstSelect *Inst) override; | 180 void lowerSelect(const InstSelect *Inst) override; |
181 void lowerStore(const InstStore *Inst) override; | 181 void lowerStore(const InstStore *Inst) override; |
182 void lowerSwitch(const InstSwitch *Inst) override; | 182 void lowerSwitch(const InstSwitch *Inst) override; |
183 void lowerUnreachable(const InstUnreachable *Inst) override; | 183 void lowerUnreachable(const InstUnreachable *Inst) override; |
184 void lowerOther(const Inst *Instr) override; | 184 void lowerOther(const Inst *Instr) override; |
185 void lowerRMW(const InstX8632FakeRMW *RMW); | 185 void lowerRMW(const typename Traits::Insts::FakeRMW *RMW); |
186 void prelowerPhis() override; | 186 void prelowerPhis() override; |
187 void lowerPhiAssignments(CfgNode *Node, | 187 void lowerPhiAssignments(CfgNode *Node, |
188 const AssignList &Assignments) override; | 188 const AssignList &Assignments) override; |
189 void doAddressOptLoad() override; | 189 void doAddressOptLoad() override; |
190 void doAddressOptStore() override; | 190 void doAddressOptStore() override; |
191 void randomlyInsertNop(float Probability) override; | 191 void randomlyInsertNop(float Probability) override; |
192 | 192 |
193 // Naive lowering of cmpxchg. | 193 // Naive lowering of cmpxchg. |
194 void lowerAtomicCmpxchg(Variable *DestPrev, Operand *Ptr, Operand *Expected, | 194 void lowerAtomicCmpxchg(Variable *DestPrev, Operand *Ptr, Operand *Expected, |
195 Operand *Desired); | 195 Operand *Desired); |
(...skipping 30 matching lines...) Expand all Loading... |
226 }; | 226 }; |
227 typedef uint32_t LegalMask; | 227 typedef uint32_t LegalMask; |
228 Operand *legalize(Operand *From, LegalMask Allowed = Legal_All, | 228 Operand *legalize(Operand *From, LegalMask Allowed = Legal_All, |
229 int32_t RegNum = Variable::NoRegister); | 229 int32_t RegNum = Variable::NoRegister); |
230 Variable *legalizeToVar(Operand *From, int32_t RegNum = Variable::NoRegister); | 230 Variable *legalizeToVar(Operand *From, int32_t RegNum = Variable::NoRegister); |
231 // Legalize the first source operand for use in the cmp instruction. | 231 // Legalize the first source operand for use in the cmp instruction. |
232 Operand *legalizeSrc0ForCmp(Operand *Src0, Operand *Src1); | 232 Operand *legalizeSrc0ForCmp(Operand *Src0, Operand *Src1); |
233 // Turn a pointer operand into a memory operand that can be | 233 // Turn a pointer operand into a memory operand that can be |
234 // used by a real load/store operation. Legalizes the operand as well. | 234 // used by a real load/store operation. Legalizes the operand as well. |
235 // This is a nop if the operand is already a legal memory operand. | 235 // This is a nop if the operand is already a legal memory operand. |
236 OperandX8632Mem *formMemoryOperand(Operand *Ptr, Type Ty, | 236 typename Traits::X86OperandMem *formMemoryOperand(Operand *Ptr, Type Ty, |
237 bool DoLegalize = true); | 237 bool DoLegalize = true); |
238 | 238 |
239 Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister); | 239 Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister); |
240 static Type stackSlotType(); | 240 static Type stackSlotType(); |
241 | 241 |
242 Variable *copyToReg(Operand *Src, int32_t RegNum = Variable::NoRegister); | 242 Variable *copyToReg(Operand *Src, int32_t RegNum = Variable::NoRegister); |
243 | 243 |
244 // Returns a vector in a register with the given constant entries. | 244 // Returns a vector in a register with the given constant entries. |
245 Variable *makeVectorOfZeros(Type Ty, int32_t RegNum = Variable::NoRegister); | 245 Variable *makeVectorOfZeros(Type Ty, int32_t RegNum = Variable::NoRegister); |
246 Variable *makeVectorOfOnes(Type Ty, int32_t RegNum = Variable::NoRegister); | 246 Variable *makeVectorOfOnes(Type Ty, int32_t RegNum = Variable::NoRegister); |
247 Variable *makeVectorOfMinusOnes(Type Ty, | 247 Variable *makeVectorOfMinusOnes(Type Ty, |
248 int32_t RegNum = Variable::NoRegister); | 248 int32_t RegNum = Variable::NoRegister); |
249 Variable *makeVectorOfHighOrderBits(Type Ty, | 249 Variable *makeVectorOfHighOrderBits(Type Ty, |
250 int32_t RegNum = Variable::NoRegister); | 250 int32_t RegNum = Variable::NoRegister); |
251 Variable *makeVectorOfFabsMask(Type Ty, | 251 Variable *makeVectorOfFabsMask(Type Ty, |
252 int32_t RegNum = Variable::NoRegister); | 252 int32_t RegNum = Variable::NoRegister); |
253 | 253 |
254 // Return a memory operand corresponding to a stack allocated Variable. | 254 // Return a memory operand corresponding to a stack allocated Variable. |
255 OperandX8632Mem *getMemoryOperandForStackSlot(Type Ty, Variable *Slot, | 255 typename Traits::X86OperandMem * |
256 uint32_t Offset = 0); | 256 getMemoryOperandForStackSlot(Type Ty, Variable *Slot, uint32_t Offset = 0); |
257 | 257 |
258 void makeRandomRegisterPermutation( | 258 void makeRandomRegisterPermutation( |
259 llvm::SmallVectorImpl<int32_t> &Permutation, | 259 llvm::SmallVectorImpl<int32_t> &Permutation, |
260 const llvm::SmallBitVector &ExcludeRegisters) const override; | 260 const llvm::SmallBitVector &ExcludeRegisters) const override; |
261 | 261 |
262 // TODO(jpp): move the helper methods below to the MachineTraits. | 262 // TODO(jpp): move the helper methods below to the MachineTraits. |
263 // The following are helpers that insert lowered x86 instructions | 263 // The following are helpers that insert lowered x86 instructions |
264 // with minimal syntactic overhead, so that the lowering code can | 264 // with minimal syntactic overhead, so that the lowering code can |
265 // look as close to assembly as practical. | 265 // look as close to assembly as practical. |
266 void _adc(Variable *Dest, Operand *Src0) { | 266 void _adc(Variable *Dest, Operand *Src0) { |
267 Context.insert(InstX8632Adc::create(Func, Dest, Src0)); | 267 Context.insert(Traits::Insts::Adc::create(Func, Dest, Src0)); |
268 } | 268 } |
269 void _adc_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) { | 269 void _adc_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { |
270 Context.insert(InstX8632AdcRMW::create(Func, DestSrc0, Src1)); | 270 Context.insert(Traits::Insts::AdcRMW::create(Func, DestSrc0, Src1)); |
271 } | 271 } |
272 void _add(Variable *Dest, Operand *Src0) { | 272 void _add(Variable *Dest, Operand *Src0) { |
273 Context.insert(InstX8632Add::create(Func, Dest, Src0)); | 273 Context.insert(Traits::Insts::Add::create(Func, Dest, Src0)); |
274 } | 274 } |
275 void _add_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) { | 275 void _add_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { |
276 Context.insert(InstX8632AddRMW::create(Func, DestSrc0, Src1)); | 276 Context.insert(Traits::Insts::AddRMW::create(Func, DestSrc0, Src1)); |
277 } | 277 } |
278 void _adjust_stack(int32_t Amount) { | 278 void _adjust_stack(int32_t Amount) { |
279 Context.insert(InstX8632AdjustStack::create( | 279 Context.insert(Traits::Insts::AdjustStack::create( |
280 Func, Amount, getPhysicalRegister(Traits::RegisterSet::Reg_esp))); | 280 Func, Amount, getPhysicalRegister(Traits::RegisterSet::Reg_esp))); |
281 } | 281 } |
282 void _addps(Variable *Dest, Operand *Src0) { | 282 void _addps(Variable *Dest, Operand *Src0) { |
283 Context.insert(InstX8632Addps::create(Func, Dest, Src0)); | 283 Context.insert(Traits::Insts::Addps::create(Func, Dest, Src0)); |
284 } | 284 } |
285 void _addss(Variable *Dest, Operand *Src0) { | 285 void _addss(Variable *Dest, Operand *Src0) { |
286 Context.insert(InstX8632Addss::create(Func, Dest, Src0)); | 286 Context.insert(Traits::Insts::Addss::create(Func, Dest, Src0)); |
287 } | 287 } |
288 void _and(Variable *Dest, Operand *Src0) { | 288 void _and(Variable *Dest, Operand *Src0) { |
289 Context.insert(InstX8632And::create(Func, Dest, Src0)); | 289 Context.insert(Traits::Insts::And::create(Func, Dest, Src0)); |
290 } | 290 } |
291 void _and_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) { | 291 void _and_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { |
292 Context.insert(InstX8632AndRMW::create(Func, DestSrc0, Src1)); | 292 Context.insert(Traits::Insts::AndRMW::create(Func, DestSrc0, Src1)); |
293 } | 293 } |
294 void _blendvps(Variable *Dest, Operand *Src0, Operand *Src1) { | 294 void _blendvps(Variable *Dest, Operand *Src0, Operand *Src1) { |
295 Context.insert(InstX8632Blendvps::create(Func, Dest, Src0, Src1)); | 295 Context.insert(Traits::Insts::Blendvps::create(Func, Dest, Src0, Src1)); |
296 } | 296 } |
297 void _br(typename Traits::Cond::BrCond Condition, CfgNode *TargetTrue, | 297 void _br(typename Traits::Cond::BrCond Condition, CfgNode *TargetTrue, |
298 CfgNode *TargetFalse) { | 298 CfgNode *TargetFalse) { |
299 Context.insert( | 299 Context.insert( |
300 InstX8632Br::create(Func, TargetTrue, TargetFalse, Condition)); | 300 Traits::Insts::Br::create(Func, TargetTrue, TargetFalse, Condition)); |
301 } | 301 } |
302 void _br(CfgNode *Target) { | 302 void _br(CfgNode *Target) { |
303 Context.insert(InstX8632Br::create(Func, Target)); | 303 Context.insert(Traits::Insts::Br::create(Func, Target)); |
304 } | 304 } |
305 void _br(typename Traits::Cond::BrCond Condition, CfgNode *Target) { | 305 void _br(typename Traits::Cond::BrCond Condition, CfgNode *Target) { |
306 Context.insert(InstX8632Br::create(Func, Target, Condition)); | 306 Context.insert(Traits::Insts::Br::create(Func, Target, Condition)); |
307 } | 307 } |
308 void _br(typename Traits::Cond::BrCond Condition, InstX8632Label *Label) { | 308 void _br(typename Traits::Cond::BrCond Condition, |
309 Context.insert(InstX8632Br::create(Func, Label, Condition)); | 309 typename Traits::Insts::Label *Label) { |
| 310 Context.insert(Traits::Insts::Br::create(Func, Label, Condition)); |
310 } | 311 } |
311 void _bsf(Variable *Dest, Operand *Src0) { | 312 void _bsf(Variable *Dest, Operand *Src0) { |
312 Context.insert(InstX8632Bsf::create(Func, Dest, Src0)); | 313 Context.insert(Traits::Insts::Bsf::create(Func, Dest, Src0)); |
313 } | 314 } |
314 void _bsr(Variable *Dest, Operand *Src0) { | 315 void _bsr(Variable *Dest, Operand *Src0) { |
315 Context.insert(InstX8632Bsr::create(Func, Dest, Src0)); | 316 Context.insert(Traits::Insts::Bsr::create(Func, Dest, Src0)); |
316 } | 317 } |
317 void _bswap(Variable *SrcDest) { | 318 void _bswap(Variable *SrcDest) { |
318 Context.insert(InstX8632Bswap::create(Func, SrcDest)); | 319 Context.insert(Traits::Insts::Bswap::create(Func, SrcDest)); |
319 } | 320 } |
320 void _cbwdq(Variable *Dest, Operand *Src0) { | 321 void _cbwdq(Variable *Dest, Operand *Src0) { |
321 Context.insert(InstX8632Cbwdq::create(Func, Dest, Src0)); | 322 Context.insert(Traits::Insts::Cbwdq::create(Func, Dest, Src0)); |
322 } | 323 } |
323 void _cmov(Variable *Dest, Operand *Src0, | 324 void _cmov(Variable *Dest, Operand *Src0, |
324 typename Traits::Cond::BrCond Condition) { | 325 typename Traits::Cond::BrCond Condition) { |
325 Context.insert(InstX8632Cmov::create(Func, Dest, Src0, Condition)); | 326 Context.insert(Traits::Insts::Cmov::create(Func, Dest, Src0, Condition)); |
326 } | 327 } |
327 void _cmp(Operand *Src0, Operand *Src1) { | 328 void _cmp(Operand *Src0, Operand *Src1) { |
328 Context.insert(InstX8632Icmp::create(Func, Src0, Src1)); | 329 Context.insert(Traits::Insts::Icmp::create(Func, Src0, Src1)); |
329 } | 330 } |
330 void _cmpps(Variable *Dest, Operand *Src0, | 331 void _cmpps(Variable *Dest, Operand *Src0, |
331 typename Traits::Cond::CmppsCond Condition) { | 332 typename Traits::Cond::CmppsCond Condition) { |
332 Context.insert(InstX8632Cmpps::create(Func, Dest, Src0, Condition)); | 333 Context.insert(Traits::Insts::Cmpps::create(Func, Dest, Src0, Condition)); |
333 } | 334 } |
334 void _cmpxchg(Operand *DestOrAddr, Variable *Eax, Variable *Desired, | 335 void _cmpxchg(Operand *DestOrAddr, Variable *Eax, Variable *Desired, |
335 bool Locked) { | 336 bool Locked) { |
336 Context.insert( | 337 Context.insert( |
337 InstX8632Cmpxchg::create(Func, DestOrAddr, Eax, Desired, Locked)); | 338 Traits::Insts::Cmpxchg::create(Func, DestOrAddr, Eax, Desired, Locked)); |
338 // Mark eax as possibly modified by cmpxchg. | 339 // Mark eax as possibly modified by cmpxchg. |
339 Context.insert( | 340 Context.insert( |
340 InstFakeDef::create(Func, Eax, llvm::dyn_cast<Variable>(DestOrAddr))); | 341 InstFakeDef::create(Func, Eax, llvm::dyn_cast<Variable>(DestOrAddr))); |
341 _set_dest_nonkillable(); | 342 _set_dest_nonkillable(); |
342 Context.insert(InstFakeUse::create(Func, Eax)); | 343 Context.insert(InstFakeUse::create(Func, Eax)); |
343 } | 344 } |
344 void _cmpxchg8b(OperandX8632Mem *Addr, Variable *Edx, Variable *Eax, | 345 void _cmpxchg8b(typename Traits::X86OperandMem *Addr, Variable *Edx, |
345 Variable *Ecx, Variable *Ebx, bool Locked) { | 346 Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked) { |
346 Context.insert( | 347 Context.insert(Traits::Insts::Cmpxchg8b::create(Func, Addr, Edx, Eax, Ecx, |
347 InstX8632Cmpxchg8b::create(Func, Addr, Edx, Eax, Ecx, Ebx, Locked)); | 348 Ebx, Locked)); |
348 // Mark edx, and eax as possibly modified by cmpxchg8b. | 349 // Mark edx, and eax as possibly modified by cmpxchg8b. |
349 Context.insert(InstFakeDef::create(Func, Edx)); | 350 Context.insert(InstFakeDef::create(Func, Edx)); |
350 _set_dest_nonkillable(); | 351 _set_dest_nonkillable(); |
351 Context.insert(InstFakeUse::create(Func, Edx)); | 352 Context.insert(InstFakeUse::create(Func, Edx)); |
352 Context.insert(InstFakeDef::create(Func, Eax)); | 353 Context.insert(InstFakeDef::create(Func, Eax)); |
353 _set_dest_nonkillable(); | 354 _set_dest_nonkillable(); |
354 Context.insert(InstFakeUse::create(Func, Eax)); | 355 Context.insert(InstFakeUse::create(Func, Eax)); |
355 } | 356 } |
356 void _cvt(Variable *Dest, Operand *Src0, InstX8632Cvt::CvtVariant Variant) { | 357 void _cvt(Variable *Dest, Operand *Src0, |
357 Context.insert(InstX8632Cvt::create(Func, Dest, Src0, Variant)); | 358 typename Traits::Insts::Cvt::CvtVariant Variant) { |
| 359 Context.insert(Traits::Insts::Cvt::create(Func, Dest, Src0, Variant)); |
358 } | 360 } |
359 void _div(Variable *Dest, Operand *Src0, Operand *Src1) { | 361 void _div(Variable *Dest, Operand *Src0, Operand *Src1) { |
360 Context.insert(InstX8632Div::create(Func, Dest, Src0, Src1)); | 362 Context.insert(Traits::Insts::Div::create(Func, Dest, Src0, Src1)); |
361 } | 363 } |
362 void _divps(Variable *Dest, Operand *Src0) { | 364 void _divps(Variable *Dest, Operand *Src0) { |
363 Context.insert(InstX8632Divps::create(Func, Dest, Src0)); | 365 Context.insert(Traits::Insts::Divps::create(Func, Dest, Src0)); |
364 } | 366 } |
365 void _divss(Variable *Dest, Operand *Src0) { | 367 void _divss(Variable *Dest, Operand *Src0) { |
366 Context.insert(InstX8632Divss::create(Func, Dest, Src0)); | 368 Context.insert(Traits::Insts::Divss::create(Func, Dest, Src0)); |
367 } | 369 } |
368 void _fld(Operand *Src0) { Context.insert(InstX8632Fld::create(Func, Src0)); } | 370 void _fld(Operand *Src0) { |
| 371 Context.insert(Traits::Insts::Fld::create(Func, Src0)); |
| 372 } |
369 void _fstp(Variable *Dest) { | 373 void _fstp(Variable *Dest) { |
370 Context.insert(InstX8632Fstp::create(Func, Dest)); | 374 Context.insert(Traits::Insts::Fstp::create(Func, Dest)); |
371 } | 375 } |
372 void _idiv(Variable *Dest, Operand *Src0, Operand *Src1) { | 376 void _idiv(Variable *Dest, Operand *Src0, Operand *Src1) { |
373 Context.insert(InstX8632Idiv::create(Func, Dest, Src0, Src1)); | 377 Context.insert(Traits::Insts::Idiv::create(Func, Dest, Src0, Src1)); |
374 } | 378 } |
375 void _imul(Variable *Dest, Operand *Src0) { | 379 void _imul(Variable *Dest, Operand *Src0) { |
376 Context.insert(InstX8632Imul::create(Func, Dest, Src0)); | 380 Context.insert(Traits::Insts::Imul::create(Func, Dest, Src0)); |
377 } | 381 } |
378 void _insertps(Variable *Dest, Operand *Src0, Operand *Src1) { | 382 void _insertps(Variable *Dest, Operand *Src0, Operand *Src1) { |
379 Context.insert(InstX8632Insertps::create(Func, Dest, Src0, Src1)); | 383 Context.insert(Traits::Insts::Insertps::create(Func, Dest, Src0, Src1)); |
380 } | 384 } |
381 void _jmp(Operand *Target) { | 385 void _jmp(Operand *Target) { |
382 Context.insert(InstX8632Jmp::create(Func, Target)); | 386 Context.insert(Traits::Insts::Jmp::create(Func, Target)); |
383 } | 387 } |
384 void _lea(Variable *Dest, Operand *Src0) { | 388 void _lea(Variable *Dest, Operand *Src0) { |
385 Context.insert(InstX8632Lea::create(Func, Dest, Src0)); | 389 Context.insert(Traits::Insts::Lea::create(Func, Dest, Src0)); |
386 } | 390 } |
387 void _mfence() { Context.insert(InstX8632Mfence::create(Func)); } | 391 void _mfence() { Context.insert(Traits::Insts::Mfence::create(Func)); } |
388 // If Dest=nullptr is passed in, then a new variable is created, | 392 // If Dest=nullptr is passed in, then a new variable is created, |
389 // marked as infinite register allocation weight, and returned | 393 // marked as infinite register allocation weight, and returned |
390 // through the in/out Dest argument. | 394 // through the in/out Dest argument. |
391 void _mov(Variable *&Dest, Operand *Src0, | 395 void _mov(Variable *&Dest, Operand *Src0, |
392 int32_t RegNum = Variable::NoRegister) { | 396 int32_t RegNum = Variable::NoRegister) { |
393 if (Dest == nullptr) | 397 if (Dest == nullptr) |
394 Dest = makeReg(Src0->getType(), RegNum); | 398 Dest = makeReg(Src0->getType(), RegNum); |
395 Context.insert(InstX8632Mov::create(Func, Dest, Src0)); | 399 Context.insert(Traits::Insts::Mov::create(Func, Dest, Src0)); |
396 } | 400 } |
397 void _mov_nonkillable(Variable *Dest, Operand *Src0) { | 401 void _mov_nonkillable(Variable *Dest, Operand *Src0) { |
398 Inst *NewInst = InstX8632Mov::create(Func, Dest, Src0); | 402 Inst *NewInst = Traits::Insts::Mov::create(Func, Dest, Src0); |
399 NewInst->setDestNonKillable(); | 403 NewInst->setDestNonKillable(); |
400 Context.insert(NewInst); | 404 Context.insert(NewInst); |
401 } | 405 } |
402 void _movd(Variable *Dest, Operand *Src0) { | 406 void _movd(Variable *Dest, Operand *Src0) { |
403 Context.insert(InstX8632Movd::create(Func, Dest, Src0)); | 407 Context.insert(Traits::Insts::Movd::create(Func, Dest, Src0)); |
404 } | 408 } |
405 void _movp(Variable *Dest, Operand *Src0) { | 409 void _movp(Variable *Dest, Operand *Src0) { |
406 Context.insert(InstX8632Movp::create(Func, Dest, Src0)); | 410 Context.insert(Traits::Insts::Movp::create(Func, Dest, Src0)); |
407 } | 411 } |
408 void _movq(Variable *Dest, Operand *Src0) { | 412 void _movq(Variable *Dest, Operand *Src0) { |
409 Context.insert(InstX8632Movq::create(Func, Dest, Src0)); | 413 Context.insert(Traits::Insts::Movq::create(Func, Dest, Src0)); |
410 } | 414 } |
411 void _movss(Variable *Dest, Variable *Src0) { | 415 void _movss(Variable *Dest, Variable *Src0) { |
412 Context.insert(InstX8632MovssRegs::create(Func, Dest, Src0)); | 416 Context.insert(Traits::Insts::MovssRegs::create(Func, Dest, Src0)); |
413 } | 417 } |
414 void _movsx(Variable *Dest, Operand *Src0) { | 418 void _movsx(Variable *Dest, Operand *Src0) { |
415 Context.insert(InstX8632Movsx::create(Func, Dest, Src0)); | 419 Context.insert(Traits::Insts::Movsx::create(Func, Dest, Src0)); |
416 } | 420 } |
417 void _movzx(Variable *Dest, Operand *Src0) { | 421 void _movzx(Variable *Dest, Operand *Src0) { |
418 Context.insert(InstX8632Movzx::create(Func, Dest, Src0)); | 422 Context.insert(Traits::Insts::Movzx::create(Func, Dest, Src0)); |
419 } | 423 } |
420 void _mul(Variable *Dest, Variable *Src0, Operand *Src1) { | 424 void _mul(Variable *Dest, Variable *Src0, Operand *Src1) { |
421 Context.insert(InstX8632Mul::create(Func, Dest, Src0, Src1)); | 425 Context.insert(Traits::Insts::Mul::create(Func, Dest, Src0, Src1)); |
422 } | 426 } |
423 void _mulps(Variable *Dest, Operand *Src0) { | 427 void _mulps(Variable *Dest, Operand *Src0) { |
424 Context.insert(InstX8632Mulps::create(Func, Dest, Src0)); | 428 Context.insert(Traits::Insts::Mulps::create(Func, Dest, Src0)); |
425 } | 429 } |
426 void _mulss(Variable *Dest, Operand *Src0) { | 430 void _mulss(Variable *Dest, Operand *Src0) { |
427 Context.insert(InstX8632Mulss::create(Func, Dest, Src0)); | 431 Context.insert(Traits::Insts::Mulss::create(Func, Dest, Src0)); |
428 } | 432 } |
429 void _neg(Variable *SrcDest) { | 433 void _neg(Variable *SrcDest) { |
430 Context.insert(InstX8632Neg::create(Func, SrcDest)); | 434 Context.insert(Traits::Insts::Neg::create(Func, SrcDest)); |
431 } | 435 } |
432 void _nop(SizeT Variant) { | 436 void _nop(SizeT Variant) { |
433 Context.insert(InstX8632Nop::create(Func, Variant)); | 437 Context.insert(Traits::Insts::Nop::create(Func, Variant)); |
434 } | 438 } |
435 void _or(Variable *Dest, Operand *Src0) { | 439 void _or(Variable *Dest, Operand *Src0) { |
436 Context.insert(InstX8632Or::create(Func, Dest, Src0)); | 440 Context.insert(Traits::Insts::Or::create(Func, Dest, Src0)); |
437 } | 441 } |
438 void _or_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) { | 442 void _or_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { |
439 Context.insert(InstX8632OrRMW::create(Func, DestSrc0, Src1)); | 443 Context.insert(Traits::Insts::OrRMW::create(Func, DestSrc0, Src1)); |
440 } | 444 } |
441 void _padd(Variable *Dest, Operand *Src0) { | 445 void _padd(Variable *Dest, Operand *Src0) { |
442 Context.insert(InstX8632Padd::create(Func, Dest, Src0)); | 446 Context.insert(Traits::Insts::Padd::create(Func, Dest, Src0)); |
443 } | 447 } |
444 void _pand(Variable *Dest, Operand *Src0) { | 448 void _pand(Variable *Dest, Operand *Src0) { |
445 Context.insert(InstX8632Pand::create(Func, Dest, Src0)); | 449 Context.insert(Traits::Insts::Pand::create(Func, Dest, Src0)); |
446 } | 450 } |
447 void _pandn(Variable *Dest, Operand *Src0) { | 451 void _pandn(Variable *Dest, Operand *Src0) { |
448 Context.insert(InstX8632Pandn::create(Func, Dest, Src0)); | 452 Context.insert(Traits::Insts::Pandn::create(Func, Dest, Src0)); |
449 } | 453 } |
450 void _pblendvb(Variable *Dest, Operand *Src0, Operand *Src1) { | 454 void _pblendvb(Variable *Dest, Operand *Src0, Operand *Src1) { |
451 Context.insert(InstX8632Pblendvb::create(Func, Dest, Src0, Src1)); | 455 Context.insert(Traits::Insts::Pblendvb::create(Func, Dest, Src0, Src1)); |
452 } | 456 } |
453 void _pcmpeq(Variable *Dest, Operand *Src0) { | 457 void _pcmpeq(Variable *Dest, Operand *Src0) { |
454 Context.insert(InstX8632Pcmpeq::create(Func, Dest, Src0)); | 458 Context.insert(Traits::Insts::Pcmpeq::create(Func, Dest, Src0)); |
455 } | 459 } |
456 void _pcmpgt(Variable *Dest, Operand *Src0) { | 460 void _pcmpgt(Variable *Dest, Operand *Src0) { |
457 Context.insert(InstX8632Pcmpgt::create(Func, Dest, Src0)); | 461 Context.insert(Traits::Insts::Pcmpgt::create(Func, Dest, Src0)); |
458 } | 462 } |
459 void _pextr(Variable *Dest, Operand *Src0, Operand *Src1) { | 463 void _pextr(Variable *Dest, Operand *Src0, Operand *Src1) { |
460 Context.insert(InstX8632Pextr::create(Func, Dest, Src0, Src1)); | 464 Context.insert(Traits::Insts::Pextr::create(Func, Dest, Src0, Src1)); |
461 } | 465 } |
462 void _pinsr(Variable *Dest, Operand *Src0, Operand *Src1) { | 466 void _pinsr(Variable *Dest, Operand *Src0, Operand *Src1) { |
463 Context.insert(InstX8632Pinsr::create(Func, Dest, Src0, Src1)); | 467 Context.insert(Traits::Insts::Pinsr::create(Func, Dest, Src0, Src1)); |
464 } | 468 } |
465 void _pmull(Variable *Dest, Operand *Src0) { | 469 void _pmull(Variable *Dest, Operand *Src0) { |
466 Context.insert(InstX8632Pmull::create(Func, Dest, Src0)); | 470 Context.insert(Traits::Insts::Pmull::create(Func, Dest, Src0)); |
467 } | 471 } |
468 void _pmuludq(Variable *Dest, Operand *Src0) { | 472 void _pmuludq(Variable *Dest, Operand *Src0) { |
469 Context.insert(InstX8632Pmuludq::create(Func, Dest, Src0)); | 473 Context.insert(Traits::Insts::Pmuludq::create(Func, Dest, Src0)); |
470 } | 474 } |
471 void _pop(Variable *Dest) { | 475 void _pop(Variable *Dest) { |
472 Context.insert(InstX8632Pop::create(Func, Dest)); | 476 Context.insert(Traits::Insts::Pop::create(Func, Dest)); |
473 } | 477 } |
474 void _por(Variable *Dest, Operand *Src0) { | 478 void _por(Variable *Dest, Operand *Src0) { |
475 Context.insert(InstX8632Por::create(Func, Dest, Src0)); | 479 Context.insert(Traits::Insts::Por::create(Func, Dest, Src0)); |
476 } | 480 } |
477 void _pshufd(Variable *Dest, Operand *Src0, Operand *Src1) { | 481 void _pshufd(Variable *Dest, Operand *Src0, Operand *Src1) { |
478 Context.insert(InstX8632Pshufd::create(Func, Dest, Src0, Src1)); | 482 Context.insert(Traits::Insts::Pshufd::create(Func, Dest, Src0, Src1)); |
479 } | 483 } |
480 void _psll(Variable *Dest, Operand *Src0) { | 484 void _psll(Variable *Dest, Operand *Src0) { |
481 Context.insert(InstX8632Psll::create(Func, Dest, Src0)); | 485 Context.insert(Traits::Insts::Psll::create(Func, Dest, Src0)); |
482 } | 486 } |
483 void _psra(Variable *Dest, Operand *Src0) { | 487 void _psra(Variable *Dest, Operand *Src0) { |
484 Context.insert(InstX8632Psra::create(Func, Dest, Src0)); | 488 Context.insert(Traits::Insts::Psra::create(Func, Dest, Src0)); |
485 } | 489 } |
486 void _psrl(Variable *Dest, Operand *Src0) { | 490 void _psrl(Variable *Dest, Operand *Src0) { |
487 Context.insert(InstX8632Psrl::create(Func, Dest, Src0)); | 491 Context.insert(Traits::Insts::Psrl::create(Func, Dest, Src0)); |
488 } | 492 } |
489 void _psub(Variable *Dest, Operand *Src0) { | 493 void _psub(Variable *Dest, Operand *Src0) { |
490 Context.insert(InstX8632Psub::create(Func, Dest, Src0)); | 494 Context.insert(Traits::Insts::Psub::create(Func, Dest, Src0)); |
491 } | 495 } |
492 void _push(Variable *Src0) { | 496 void _push(Variable *Src0) { |
493 Context.insert(InstX8632Push::create(Func, Src0)); | 497 Context.insert(Traits::Insts::Push::create(Func, Src0)); |
494 } | 498 } |
495 void _pxor(Variable *Dest, Operand *Src0) { | 499 void _pxor(Variable *Dest, Operand *Src0) { |
496 Context.insert(InstX8632Pxor::create(Func, Dest, Src0)); | 500 Context.insert(Traits::Insts::Pxor::create(Func, Dest, Src0)); |
497 } | 501 } |
498 void _ret(Variable *Src0 = nullptr) { | 502 void _ret(Variable *Src0 = nullptr) { |
499 Context.insert(InstX8632Ret::create(Func, Src0)); | 503 Context.insert(Traits::Insts::Ret::create(Func, Src0)); |
500 } | 504 } |
501 void _rol(Variable *Dest, Operand *Src0) { | 505 void _rol(Variable *Dest, Operand *Src0) { |
502 Context.insert(InstX8632Rol::create(Func, Dest, Src0)); | 506 Context.insert(Traits::Insts::Rol::create(Func, Dest, Src0)); |
503 } | 507 } |
504 void _sar(Variable *Dest, Operand *Src0) { | 508 void _sar(Variable *Dest, Operand *Src0) { |
505 Context.insert(InstX8632Sar::create(Func, Dest, Src0)); | 509 Context.insert(Traits::Insts::Sar::create(Func, Dest, Src0)); |
506 } | 510 } |
507 void _sbb(Variable *Dest, Operand *Src0) { | 511 void _sbb(Variable *Dest, Operand *Src0) { |
508 Context.insert(InstX8632Sbb::create(Func, Dest, Src0)); | 512 Context.insert(Traits::Insts::Sbb::create(Func, Dest, Src0)); |
509 } | 513 } |
510 void _sbb_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) { | 514 void _sbb_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { |
511 Context.insert(InstX8632SbbRMW::create(Func, DestSrc0, Src1)); | 515 Context.insert(Traits::Insts::SbbRMW::create(Func, DestSrc0, Src1)); |
512 } | 516 } |
513 void _setcc(Variable *Dest, typename Traits::Cond::BrCond Condition) { | 517 void _setcc(Variable *Dest, typename Traits::Cond::BrCond Condition) { |
514 Context.insert(InstX8632Setcc::create(Func, Dest, Condition)); | 518 Context.insert(Traits::Insts::Setcc::create(Func, Dest, Condition)); |
515 } | 519 } |
516 void _shl(Variable *Dest, Operand *Src0) { | 520 void _shl(Variable *Dest, Operand *Src0) { |
517 Context.insert(InstX8632Shl::create(Func, Dest, Src0)); | 521 Context.insert(Traits::Insts::Shl::create(Func, Dest, Src0)); |
518 } | 522 } |
519 void _shld(Variable *Dest, Variable *Src0, Variable *Src1) { | 523 void _shld(Variable *Dest, Variable *Src0, Variable *Src1) { |
520 Context.insert(InstX8632Shld::create(Func, Dest, Src0, Src1)); | 524 Context.insert(Traits::Insts::Shld::create(Func, Dest, Src0, Src1)); |
521 } | 525 } |
522 void _shr(Variable *Dest, Operand *Src0) { | 526 void _shr(Variable *Dest, Operand *Src0) { |
523 Context.insert(InstX8632Shr::create(Func, Dest, Src0)); | 527 Context.insert(Traits::Insts::Shr::create(Func, Dest, Src0)); |
524 } | 528 } |
525 void _shrd(Variable *Dest, Variable *Src0, Variable *Src1) { | 529 void _shrd(Variable *Dest, Variable *Src0, Variable *Src1) { |
526 Context.insert(InstX8632Shrd::create(Func, Dest, Src0, Src1)); | 530 Context.insert(Traits::Insts::Shrd::create(Func, Dest, Src0, Src1)); |
527 } | 531 } |
528 void _shufps(Variable *Dest, Operand *Src0, Operand *Src1) { | 532 void _shufps(Variable *Dest, Operand *Src0, Operand *Src1) { |
529 Context.insert(InstX8632Shufps::create(Func, Dest, Src0, Src1)); | 533 Context.insert(Traits::Insts::Shufps::create(Func, Dest, Src0, Src1)); |
530 } | 534 } |
531 void _sqrtss(Variable *Dest, Operand *Src0) { | 535 void _sqrtss(Variable *Dest, Operand *Src0) { |
532 Context.insert(InstX8632Sqrtss::create(Func, Dest, Src0)); | 536 Context.insert(Traits::Insts::Sqrtss::create(Func, Dest, Src0)); |
533 } | 537 } |
534 void _store(Operand *Value, OperandX8632 *Mem) { | 538 void _store(Operand *Value, typename Traits::X86Operand *Mem) { |
535 Context.insert(InstX8632Store::create(Func, Value, Mem)); | 539 Context.insert(Traits::Insts::Store::create(Func, Value, Mem)); |
536 } | 540 } |
537 void _storep(Variable *Value, OperandX8632Mem *Mem) { | 541 void _storep(Variable *Value, typename Traits::X86OperandMem *Mem) { |
538 Context.insert(InstX8632StoreP::create(Func, Value, Mem)); | 542 Context.insert(Traits::Insts::StoreP::create(Func, Value, Mem)); |
539 } | 543 } |
540 void _storeq(Variable *Value, OperandX8632Mem *Mem) { | 544 void _storeq(Variable *Value, typename Traits::X86OperandMem *Mem) { |
541 Context.insert(InstX8632StoreQ::create(Func, Value, Mem)); | 545 Context.insert(Traits::Insts::StoreQ::create(Func, Value, Mem)); |
542 } | 546 } |
543 void _sub(Variable *Dest, Operand *Src0) { | 547 void _sub(Variable *Dest, Operand *Src0) { |
544 Context.insert(InstX8632Sub::create(Func, Dest, Src0)); | 548 Context.insert(Traits::Insts::Sub::create(Func, Dest, Src0)); |
545 } | 549 } |
546 void _sub_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) { | 550 void _sub_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { |
547 Context.insert(InstX8632SubRMW::create(Func, DestSrc0, Src1)); | 551 Context.insert(Traits::Insts::SubRMW::create(Func, DestSrc0, Src1)); |
548 } | 552 } |
549 void _subps(Variable *Dest, Operand *Src0) { | 553 void _subps(Variable *Dest, Operand *Src0) { |
550 Context.insert(InstX8632Subps::create(Func, Dest, Src0)); | 554 Context.insert(Traits::Insts::Subps::create(Func, Dest, Src0)); |
551 } | 555 } |
552 void _subss(Variable *Dest, Operand *Src0) { | 556 void _subss(Variable *Dest, Operand *Src0) { |
553 Context.insert(InstX8632Subss::create(Func, Dest, Src0)); | 557 Context.insert(Traits::Insts::Subss::create(Func, Dest, Src0)); |
554 } | 558 } |
555 void _test(Operand *Src0, Operand *Src1) { | 559 void _test(Operand *Src0, Operand *Src1) { |
556 Context.insert(InstX8632Test::create(Func, Src0, Src1)); | 560 Context.insert(Traits::Insts::Test::create(Func, Src0, Src1)); |
557 } | 561 } |
558 void _ucomiss(Operand *Src0, Operand *Src1) { | 562 void _ucomiss(Operand *Src0, Operand *Src1) { |
559 Context.insert(InstX8632Ucomiss::create(Func, Src0, Src1)); | 563 Context.insert(Traits::Insts::Ucomiss::create(Func, Src0, Src1)); |
560 } | 564 } |
561 void _ud2() { Context.insert(InstX8632UD2::create(Func)); } | 565 void _ud2() { Context.insert(Traits::Insts::UD2::create(Func)); } |
562 void _xadd(Operand *Dest, Variable *Src, bool Locked) { | 566 void _xadd(Operand *Dest, Variable *Src, bool Locked) { |
563 Context.insert(InstX8632Xadd::create(Func, Dest, Src, Locked)); | 567 Context.insert(Traits::Insts::Xadd::create(Func, Dest, Src, Locked)); |
564 // The xadd exchanges Dest and Src (modifying Src). | 568 // The xadd exchanges Dest and Src (modifying Src). |
565 // Model that update with a FakeDef followed by a FakeUse. | 569 // Model that update with a FakeDef followed by a FakeUse. |
566 Context.insert( | 570 Context.insert( |
567 InstFakeDef::create(Func, Src, llvm::dyn_cast<Variable>(Dest))); | 571 InstFakeDef::create(Func, Src, llvm::dyn_cast<Variable>(Dest))); |
568 _set_dest_nonkillable(); | 572 _set_dest_nonkillable(); |
569 Context.insert(InstFakeUse::create(Func, Src)); | 573 Context.insert(InstFakeUse::create(Func, Src)); |
570 } | 574 } |
571 void _xchg(Operand *Dest, Variable *Src) { | 575 void _xchg(Operand *Dest, Variable *Src) { |
572 Context.insert(InstX8632Xchg::create(Func, Dest, Src)); | 576 Context.insert(Traits::Insts::Xchg::create(Func, Dest, Src)); |
573 // The xchg modifies Dest and Src -- model that update with a | 577 // The xchg modifies Dest and Src -- model that update with a |
574 // FakeDef/FakeUse. | 578 // FakeDef/FakeUse. |
575 Context.insert( | 579 Context.insert( |
576 InstFakeDef::create(Func, Src, llvm::dyn_cast<Variable>(Dest))); | 580 InstFakeDef::create(Func, Src, llvm::dyn_cast<Variable>(Dest))); |
577 _set_dest_nonkillable(); | 581 _set_dest_nonkillable(); |
578 Context.insert(InstFakeUse::create(Func, Src)); | 582 Context.insert(InstFakeUse::create(Func, Src)); |
579 } | 583 } |
580 void _xor(Variable *Dest, Operand *Src0) { | 584 void _xor(Variable *Dest, Operand *Src0) { |
581 Context.insert(InstX8632Xor::create(Func, Dest, Src0)); | 585 Context.insert(Traits::Insts::Xor::create(Func, Dest, Src0)); |
582 } | 586 } |
583 void _xor_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) { | 587 void _xor_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { |
584 Context.insert(InstX8632XorRMW::create(Func, DestSrc0, Src1)); | 588 Context.insert(Traits::Insts::XorRMW::create(Func, DestSrc0, Src1)); |
585 } | 589 } |
586 void _set_dest_nonkillable() { | 590 void _set_dest_nonkillable() { |
587 Context.getLastInserted()->setDestNonKillable(); | 591 Context.getLastInserted()->setDestNonKillable(); |
588 } | 592 } |
589 | 593 |
590 bool optimizeScalarMul(Variable *Dest, Operand *Src0, int32_t Src1); | 594 bool optimizeScalarMul(Variable *Dest, Operand *Src0, int32_t Src1); |
591 void findRMW(); | 595 void findRMW(); |
592 | 596 |
593 typename Traits::InstructionSet InstructionSet = | 597 typename Traits::InstructionSet InstructionSet = |
594 Traits::InstructionSet::Begin; | 598 Traits::InstructionSet::Begin; |
595 bool IsEbpBasedFrame = false; | 599 bool IsEbpBasedFrame = false; |
596 bool NeedsStackAlignment = false; | 600 bool NeedsStackAlignment = false; |
597 size_t SpillAreaSizeBytes = 0; | 601 size_t SpillAreaSizeBytes = 0; |
598 llvm::SmallBitVector TypeToRegisterSet[IceType_NUM]; | 602 llvm::SmallBitVector TypeToRegisterSet[IceType_NUM]; |
599 llvm::SmallBitVector ScratchRegs; | 603 llvm::SmallBitVector ScratchRegs; |
600 llvm::SmallBitVector RegsUsed; | 604 llvm::SmallBitVector RegsUsed; |
601 VarList PhysicalRegisters[IceType_NUM]; | 605 VarList PhysicalRegisters[IceType_NUM]; |
602 static IceString RegNames[]; | |
603 | 606 |
604 // Randomize a given immediate operand | 607 // Randomize a given immediate operand |
605 Operand *randomizeOrPoolImmediate(Constant *Immediate, | 608 Operand *randomizeOrPoolImmediate(Constant *Immediate, |
606 int32_t RegNum = Variable::NoRegister); | 609 int32_t RegNum = Variable::NoRegister); |
607 OperandX8632Mem * | 610 typename Traits::X86OperandMem * |
608 randomizeOrPoolImmediate(OperandX8632Mem *MemOperand, | 611 randomizeOrPoolImmediate(typename Traits::X86OperandMem *MemOperand, |
609 int32_t RegNum = Variable::NoRegister); | 612 int32_t RegNum = Variable::NoRegister); |
610 bool RandomizationPoolingPaused = false; | 613 bool RandomizationPoolingPaused = false; |
611 | 614 |
612 private: | 615 private: |
613 ~TargetX86Base() override {} | 616 ~TargetX86Base() override {} |
614 BoolFolding FoldingInfo; | 617 BoolFolding FoldingInfo; |
615 }; | 618 }; |
616 } // end of namespace X86Internal | 619 } // end of namespace X86Internal |
617 } // end of namespace Ice | 620 } // end of namespace Ice |
618 | 621 |
619 #include "IceTargetLoweringX86BaseImpl.h" | 622 #include "IceTargetLoweringX86BaseImpl.h" |
620 | 623 |
621 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASE_H | 624 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASE_H |
OLD | NEW |