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 /// \file | 10 /// \file |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 | 243 |
244 void eliminateNextVectorSextInstruction(Variable *SignExtendedResult); | 244 void eliminateNextVectorSextInstruction(Variable *SignExtendedResult); |
245 | 245 |
246 void scalarizeArithmetic(InstArithmetic::OpKind K, Variable *Dest, | 246 void scalarizeArithmetic(InstArithmetic::OpKind K, Variable *Dest, |
247 Operand *Src0, Operand *Src1); | 247 Operand *Src0, Operand *Src1); |
248 | 248 |
249 /// Emit a fake use of esp to make sure esp stays alive for the entire | 249 /// Emit a fake use of esp to make sure esp stays alive for the entire |
250 /// function. Otherwise some esp adjustments get dead-code eliminated. | 250 /// function. Otherwise some esp adjustments get dead-code eliminated. |
251 void keepEspLiveAtExit() { | 251 void keepEspLiveAtExit() { |
252 Variable *esp = Func->getTarget()->getPhysicalRegister(getStackReg()); | 252 Variable *esp = Func->getTarget()->getPhysicalRegister(getStackReg()); |
253 Context.insert(InstFakeUse::create(Func, esp)); | 253 Context.insert<InstFakeUse>(esp); |
254 } | 254 } |
255 | 255 |
256 /// Operand legalization helpers. To deal with address mode constraints, the | 256 /// Operand legalization helpers. To deal with address mode constraints, the |
257 /// helpers will create a new Operand and emit instructions that guarantee | 257 /// helpers will create a new Operand and emit instructions that guarantee |
258 /// that the Operand kind is one of those indicated by the LegalMask (a | 258 /// that the Operand kind is one of those indicated by the LegalMask (a |
259 /// bitmask of allowed kinds). If the input Operand is known to already meet | 259 /// bitmask of allowed kinds). If the input Operand is known to already meet |
260 /// the constraints, it may be simply returned as the result, without creating | 260 /// the constraints, it may be simply returned as the result, without creating |
261 /// any new instructions or operands. | 261 /// any new instructions or operands. |
262 enum OperandLegalization { | 262 enum OperandLegalization { |
263 Legal_None = 0, | 263 Legal_None = 0, |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 | 320 |
321 void | 321 void |
322 makeRandomRegisterPermutation(llvm::SmallVectorImpl<int32_t> &Permutation, | 322 makeRandomRegisterPermutation(llvm::SmallVectorImpl<int32_t> &Permutation, |
323 const llvm::SmallBitVector &ExcludeRegisters, | 323 const llvm::SmallBitVector &ExcludeRegisters, |
324 uint64_t Salt) const override; | 324 uint64_t Salt) const override; |
325 | 325 |
326 /// The following are helpers that insert lowered x86 instructions with | 326 /// The following are helpers that insert lowered x86 instructions with |
327 /// minimal syntactic overhead, so that the lowering code can look as close to | 327 /// minimal syntactic overhead, so that the lowering code can look as close to |
328 /// assembly as practical. | 328 /// assembly as practical. |
329 void _adc(Variable *Dest, Operand *Src0) { | 329 void _adc(Variable *Dest, Operand *Src0) { |
330 Context.insert(Traits::Insts::Adc::create(Func, Dest, Src0)); | 330 Context.insert<typename Traits::Insts::Adc>(Dest, Src0); |
331 } | 331 } |
332 void _adc_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { | 332 void _adc_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { |
333 Context.insert(Traits::Insts::AdcRMW::create(Func, DestSrc0, Src1)); | 333 Context.insert<typename Traits::Insts::AdcRMW>(DestSrc0, Src1); |
334 } | 334 } |
335 void _add(Variable *Dest, Operand *Src0) { | 335 void _add(Variable *Dest, Operand *Src0) { |
336 Context.insert(Traits::Insts::Add::create(Func, Dest, Src0)); | 336 Context.insert<typename Traits::Insts::Add>(Dest, Src0); |
337 } | 337 } |
338 void _add_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { | 338 void _add_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { |
339 Context.insert(Traits::Insts::AddRMW::create(Func, DestSrc0, Src1)); | 339 Context.insert<typename Traits::Insts::AddRMW>(DestSrc0, Src1); |
340 } | 340 } |
341 void _addps(Variable *Dest, Operand *Src0) { | 341 void _addps(Variable *Dest, Operand *Src0) { |
342 Context.insert(Traits::Insts::Addps::create(Func, Dest, Src0)); | 342 Context.insert<typename Traits::Insts::Addps>(Dest, Src0); |
343 } | 343 } |
344 void _addss(Variable *Dest, Operand *Src0) { | 344 void _addss(Variable *Dest, Operand *Src0) { |
345 Context.insert(Traits::Insts::Addss::create(Func, Dest, Src0)); | 345 Context.insert<typename Traits::Insts::Addss>(Dest, Src0); |
346 } | 346 } |
347 void _and(Variable *Dest, Operand *Src0) { | 347 void _and(Variable *Dest, Operand *Src0) { |
348 Context.insert(Traits::Insts::And::create(Func, Dest, Src0)); | 348 Context.insert<typename Traits::Insts::And>(Dest, Src0); |
349 } | 349 } |
350 void _andnps(Variable *Dest, Operand *Src0) { | 350 void _andnps(Variable *Dest, Operand *Src0) { |
351 Context.insert(Traits::Insts::Andnps::create(Func, Dest, Src0)); | 351 Context.insert<typename Traits::Insts::Andnps>(Dest, Src0); |
352 } | 352 } |
353 void _andps(Variable *Dest, Operand *Src0) { | 353 void _andps(Variable *Dest, Operand *Src0) { |
354 Context.insert(Traits::Insts::Andps::create(Func, Dest, Src0)); | 354 Context.insert<typename Traits::Insts::Andps>(Dest, Src0); |
355 } | 355 } |
356 void _and_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { | 356 void _and_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { |
357 Context.insert(Traits::Insts::AndRMW::create(Func, DestSrc0, Src1)); | 357 Context.insert<typename Traits::Insts::AndRMW>(DestSrc0, Src1); |
358 } | 358 } |
359 void _blendvps(Variable *Dest, Operand *Src0, Operand *Src1) { | 359 void _blendvps(Variable *Dest, Operand *Src0, Operand *Src1) { |
360 Context.insert(Traits::Insts::Blendvps::create(Func, Dest, Src0, Src1)); | 360 Context.insert<typename Traits::Insts::Blendvps>(Dest, Src0, Src1); |
361 } | 361 } |
362 void _br(typename Traits::Cond::BrCond Condition, CfgNode *TargetTrue, | 362 void _br(typename Traits::Cond::BrCond Condition, CfgNode *TargetTrue, |
363 CfgNode *TargetFalse) { | 363 CfgNode *TargetFalse) { |
364 Context.insert(Traits::Insts::Br::create( | 364 Context.insert<typename Traits::Insts::Br>( |
365 Func, TargetTrue, TargetFalse, Condition, Traits::Insts::Br::Far)); | 365 TargetTrue, TargetFalse, Condition, Traits::Insts::Br::Far); |
366 } | 366 } |
367 void _br(CfgNode *Target) { | 367 void _br(CfgNode *Target) { |
368 Context.insert( | 368 Context.insert<typename Traits::Insts::Br>(Target, Traits::Insts::Br::Far); |
369 Traits::Insts::Br::create(Func, Target, Traits::Insts::Br::Far)); | |
370 } | 369 } |
371 void _br(typename Traits::Cond::BrCond Condition, CfgNode *Target) { | 370 void _br(typename Traits::Cond::BrCond Condition, CfgNode *Target) { |
372 Context.insert(Traits::Insts::Br::create(Func, Target, Condition, | 371 Context.insert<typename Traits::Insts::Br>(Target, Condition, |
373 Traits::Insts::Br::Far)); | 372 Traits::Insts::Br::Far); |
374 } | 373 } |
375 void _br(typename Traits::Cond::BrCond Condition, | 374 void _br(typename Traits::Cond::BrCond Condition, |
376 typename Traits::Insts::Label *Label, | 375 typename Traits::Insts::Label *Label, |
377 typename Traits::Insts::Br::Mode Kind = Traits::Insts::Br::Near) { | 376 typename Traits::Insts::Br::Mode Kind = Traits::Insts::Br::Near) { |
378 Context.insert(Traits::Insts::Br::create(Func, Label, Condition, Kind)); | 377 Context.insert<typename Traits::Insts::Br>(Label, Condition, Kind); |
379 } | 378 } |
380 void _bsf(Variable *Dest, Operand *Src0) { | 379 void _bsf(Variable *Dest, Operand *Src0) { |
381 Context.insert(Traits::Insts::Bsf::create(Func, Dest, Src0)); | 380 Context.insert<typename Traits::Insts::Bsf>(Dest, Src0); |
382 } | 381 } |
383 void _bsr(Variable *Dest, Operand *Src0) { | 382 void _bsr(Variable *Dest, Operand *Src0) { |
384 Context.insert(Traits::Insts::Bsr::create(Func, Dest, Src0)); | 383 Context.insert<typename Traits::Insts::Bsr>(Dest, Src0); |
385 } | 384 } |
386 void _bswap(Variable *SrcDest) { | 385 void _bswap(Variable *SrcDest) { |
387 Context.insert(Traits::Insts::Bswap::create(Func, SrcDest)); | 386 Context.insert<typename Traits::Insts::Bswap>(SrcDest); |
388 } | 387 } |
389 void _cbwdq(Variable *Dest, Operand *Src0) { | 388 void _cbwdq(Variable *Dest, Operand *Src0) { |
390 Context.insert(Traits::Insts::Cbwdq::create(Func, Dest, Src0)); | 389 Context.insert<typename Traits::Insts::Cbwdq>(Dest, Src0); |
391 } | 390 } |
392 void _cmov(Variable *Dest, Operand *Src0, | 391 void _cmov(Variable *Dest, Operand *Src0, |
393 typename Traits::Cond::BrCond Condition) { | 392 typename Traits::Cond::BrCond Condition) { |
394 Context.insert(Traits::Insts::Cmov::create(Func, Dest, Src0, Condition)); | 393 Context.insert<typename Traits::Insts::Cmov>(Dest, Src0, Condition); |
395 } | 394 } |
396 void _cmp(Operand *Src0, Operand *Src1) { | 395 void _cmp(Operand *Src0, Operand *Src1) { |
397 Context.insert(Traits::Insts::Icmp::create(Func, Src0, Src1)); | 396 Context.insert<typename Traits::Insts::Icmp>(Src0, Src1); |
398 } | 397 } |
399 void _cmpps(Variable *Dest, Operand *Src0, | 398 void _cmpps(Variable *Dest, Operand *Src0, |
400 typename Traits::Cond::CmppsCond Condition) { | 399 typename Traits::Cond::CmppsCond Condition) { |
401 Context.insert(Traits::Insts::Cmpps::create(Func, Dest, Src0, Condition)); | 400 Context.insert<typename Traits::Insts::Cmpps>(Dest, Src0, Condition); |
402 } | 401 } |
403 void _cmpxchg(Operand *DestOrAddr, Variable *Eax, Variable *Desired, | 402 void _cmpxchg(Operand *DestOrAddr, Variable *Eax, Variable *Desired, |
404 bool Locked) { | 403 bool Locked) { |
405 Context.insert( | 404 Context.insert<typename Traits::Insts::Cmpxchg>(DestOrAddr, Eax, Desired, |
406 Traits::Insts::Cmpxchg::create(Func, DestOrAddr, Eax, Desired, Locked)); | 405 Locked); |
407 // Mark eax as possibly modified by cmpxchg. | 406 // Mark eax as possibly modified by cmpxchg. |
408 Context.insert( | 407 Context.insert<InstFakeDef>(Eax, llvm::dyn_cast<Variable>(DestOrAddr)); |
409 InstFakeDef::create(Func, Eax, llvm::dyn_cast<Variable>(DestOrAddr))); | |
410 _set_dest_redefined(); | 408 _set_dest_redefined(); |
411 Context.insert(InstFakeUse::create(Func, Eax)); | 409 Context.insert<InstFakeUse>(Eax); |
412 } | 410 } |
413 void _cmpxchg8b(typename Traits::X86OperandMem *Addr, Variable *Edx, | 411 void _cmpxchg8b(typename Traits::X86OperandMem *Addr, Variable *Edx, |
414 Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked) { | 412 Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked) { |
415 Context.insert(Traits::Insts::Cmpxchg8b::create(Func, Addr, Edx, Eax, Ecx, | 413 Context.insert<typename Traits::Insts::Cmpxchg8b>(Addr, Edx, Eax, Ecx, Ebx, |
416 Ebx, Locked)); | 414 Locked); |
417 // Mark edx, and eax as possibly modified by cmpxchg8b. | 415 // Mark edx, and eax as possibly modified by cmpxchg8b. |
418 Context.insert(InstFakeDef::create(Func, Edx)); | 416 Context.insert<InstFakeDef>(Edx); |
419 _set_dest_redefined(); | 417 _set_dest_redefined(); |
420 Context.insert(InstFakeUse::create(Func, Edx)); | 418 Context.insert<InstFakeUse>(Edx); |
421 Context.insert(InstFakeDef::create(Func, Eax)); | 419 Context.insert<InstFakeDef>(Eax); |
422 _set_dest_redefined(); | 420 _set_dest_redefined(); |
423 Context.insert(InstFakeUse::create(Func, Eax)); | 421 Context.insert<InstFakeUse>(Eax); |
424 } | 422 } |
425 void _cvt(Variable *Dest, Operand *Src0, | 423 void _cvt(Variable *Dest, Operand *Src0, |
426 typename Traits::Insts::Cvt::CvtVariant Variant) { | 424 typename Traits::Insts::Cvt::CvtVariant Variant) { |
427 Context.insert(Traits::Insts::Cvt::create(Func, Dest, Src0, Variant)); | 425 Context.insert<typename Traits::Insts::Cvt>(Dest, Src0, Variant); |
428 } | 426 } |
429 void _div(Variable *Dest, Operand *Src0, Operand *Src1) { | 427 void _div(Variable *Dest, Operand *Src0, Operand *Src1) { |
430 Context.insert(Traits::Insts::Div::create(Func, Dest, Src0, Src1)); | 428 Context.insert<typename Traits::Insts::Div>(Dest, Src0, Src1); |
431 } | 429 } |
432 void _divps(Variable *Dest, Operand *Src0) { | 430 void _divps(Variable *Dest, Operand *Src0) { |
433 Context.insert(Traits::Insts::Divps::create(Func, Dest, Src0)); | 431 Context.insert<typename Traits::Insts::Divps>(Dest, Src0); |
434 } | 432 } |
435 void _divss(Variable *Dest, Operand *Src0) { | 433 void _divss(Variable *Dest, Operand *Src0) { |
436 Context.insert(Traits::Insts::Divss::create(Func, Dest, Src0)); | 434 Context.insert<typename Traits::Insts::Divss>(Dest, Src0); |
437 } | 435 } |
438 template <typename T = Traits> | 436 template <typename T = Traits> |
439 typename std::enable_if<T::UsesX87, void>::type _fld(Operand *Src0) { | 437 typename std::enable_if<T::UsesX87, void>::type _fld(Operand *Src0) { |
440 Context.insert(Traits::Insts::template Fld<>::create(Func, Src0)); | 438 Context.insert<typename Traits::Insts::template Fld<>>(Src0); |
441 } | 439 } |
442 // TODO(jpp): when implementing the X8664 calling convention, make sure x8664 | 440 // TODO(jpp): when implementing the X8664 calling convention, make sure x8664 |
443 // does not invoke this method, and remove it. | 441 // does not invoke this method, and remove it. |
444 template <typename T = Traits> | 442 template <typename T = Traits> |
445 typename std::enable_if<!T::UsesX87, void>::type _fld(Operand *) { | 443 typename std::enable_if<!T::UsesX87, void>::type _fld(Operand *) { |
446 llvm::report_fatal_error("fld is not available in x86-64"); | 444 llvm::report_fatal_error("fld is not available in x86-64"); |
447 } | 445 } |
448 template <typename T = Traits> | 446 template <typename T = Traits> |
449 typename std::enable_if<T::UsesX87, void>::type _fstp(Variable *Dest) { | 447 typename std::enable_if<T::UsesX87, void>::type _fstp(Variable *Dest) { |
450 Context.insert(Traits::Insts::template Fstp<>::create(Func, Dest)); | 448 Context.insert<typename Traits::Insts::template Fstp<>>(Dest); |
451 } | 449 } |
452 // TODO(jpp): when implementing the X8664 calling convention, make sure x8664 | 450 // TODO(jpp): when implementing the X8664 calling convention, make sure x8664 |
453 // does not invoke this method, and remove it. | 451 // does not invoke this method, and remove it. |
454 template <typename T = Traits> | 452 template <typename T = Traits> |
455 typename std::enable_if<!T::UsesX87, void>::type _fstp(Variable *) { | 453 typename std::enable_if<!T::UsesX87, void>::type _fstp(Variable *) { |
456 llvm::report_fatal_error("fstp is not available in x86-64"); | 454 llvm::report_fatal_error("fstp is not available in x86-64"); |
457 } | 455 } |
458 void _idiv(Variable *Dest, Operand *Src0, Operand *Src1) { | 456 void _idiv(Variable *Dest, Operand *Src0, Operand *Src1) { |
459 Context.insert(Traits::Insts::Idiv::create(Func, Dest, Src0, Src1)); | 457 Context.insert<typename Traits::Insts::Idiv>(Dest, Src0, Src1); |
460 } | 458 } |
461 void _imul(Variable *Dest, Operand *Src0) { | 459 void _imul(Variable *Dest, Operand *Src0) { |
462 Context.insert(Traits::Insts::Imul::create(Func, Dest, Src0)); | 460 Context.insert<typename Traits::Insts::Imul>(Dest, Src0); |
463 } | 461 } |
464 void _imul_imm(Variable *Dest, Operand *Src0, Constant *Imm) { | 462 void _imul_imm(Variable *Dest, Operand *Src0, Constant *Imm) { |
465 Context.insert(Traits::Insts::ImulImm::create(Func, Dest, Src0, Imm)); | 463 Context.insert<typename Traits::Insts::ImulImm>(Dest, Src0, Imm); |
466 } | 464 } |
467 void _insertps(Variable *Dest, Operand *Src0, Operand *Src1) { | 465 void _insertps(Variable *Dest, Operand *Src0, Operand *Src1) { |
468 Context.insert(Traits::Insts::Insertps::create(Func, Dest, Src0, Src1)); | 466 Context.insert<typename Traits::Insts::Insertps>(Dest, Src0, Src1); |
469 } | 467 } |
470 void _jmp(Operand *Target) { | 468 void _jmp(Operand *Target) { |
471 Context.insert(Traits::Insts::Jmp::create(Func, Target)); | 469 Context.insert<typename Traits::Insts::Jmp>(Target); |
472 } | 470 } |
473 void _lea(Variable *Dest, Operand *Src0) { | 471 void _lea(Variable *Dest, Operand *Src0) { |
474 Context.insert(Traits::Insts::Lea::create(Func, Dest, Src0)); | 472 Context.insert<typename Traits::Insts::Lea>(Dest, Src0); |
475 } | 473 } |
476 void _mfence() { Context.insert(Traits::Insts::Mfence::create(Func)); } | 474 void _mfence() { Context.insert<typename Traits::Insts::Mfence>(); } |
477 /// Moves can be used to redefine registers, creating "partial kills" for | 475 /// Moves can be used to redefine registers, creating "partial kills" for |
478 /// liveness. Mark where moves are used in this way. | 476 /// liveness. Mark where moves are used in this way. |
479 void _redefined(Inst *MovInst, bool IsRedefinition = true) { | 477 void _redefined(Inst *MovInst, bool IsRedefinition = true) { |
480 if (IsRedefinition) | 478 if (IsRedefinition) |
481 MovInst->setDestRedefined(); | 479 MovInst->setDestRedefined(); |
482 } | 480 } |
483 /// If Dest=nullptr is passed in, then a new variable is created, marked as | 481 /// If Dest=nullptr is passed in, then a new variable is created, marked as |
484 /// infinite register allocation weight, and returned through the in/out Dest | 482 /// infinite register allocation weight, and returned through the in/out Dest |
485 /// argument. | 483 /// argument. |
486 Inst *_mov(Variable *&Dest, Operand *Src0, | 484 typename Traits::Insts::Mov *_mov(Variable *&Dest, Operand *Src0, |
487 int32_t RegNum = Variable::NoRegister) { | 485 int32_t RegNum = Variable::NoRegister) { |
488 if (Dest == nullptr) | 486 if (Dest == nullptr) |
489 Dest = makeReg(Src0->getType(), RegNum); | 487 Dest = makeReg(Src0->getType(), RegNum); |
490 Inst *NewInst = Traits::Insts::Mov::create(Func, Dest, Src0); | 488 return Context.insert<typename Traits::Insts::Mov>(Dest, Src0); |
491 Context.insert(NewInst); | 489 } |
492 return NewInst; | 490 typename Traits::Insts::Movp *_movp(Variable *Dest, Operand *Src0) { |
493 } | 491 return Context.insert<typename Traits::Insts::Movp>(Dest, Src0); |
494 Inst *_movp(Variable *Dest, Operand *Src0) { | |
495 Inst *NewInst = Traits::Insts::Movp::create(Func, Dest, Src0); | |
496 Context.insert(NewInst); | |
497 return NewInst; | |
498 } | 492 } |
499 void _movd(Variable *Dest, Operand *Src0) { | 493 void _movd(Variable *Dest, Operand *Src0) { |
500 Context.insert(Traits::Insts::Movd::create(Func, Dest, Src0)); | 494 Context.insert<typename Traits::Insts::Movd>(Dest, Src0); |
501 } | 495 } |
502 void _movq(Variable *Dest, Operand *Src0) { | 496 void _movq(Variable *Dest, Operand *Src0) { |
503 Context.insert(Traits::Insts::Movq::create(Func, Dest, Src0)); | 497 Context.insert<typename Traits::Insts::Movq>(Dest, Src0); |
504 } | 498 } |
505 void _movss(Variable *Dest, Variable *Src0) { | 499 void _movss(Variable *Dest, Variable *Src0) { |
506 Context.insert(Traits::Insts::MovssRegs::create(Func, Dest, Src0)); | 500 Context.insert<typename Traits::Insts::MovssRegs>(Dest, Src0); |
507 } | 501 } |
508 void _movsx(Variable *Dest, Operand *Src0) { | 502 void _movsx(Variable *Dest, Operand *Src0) { |
509 Context.insert(Traits::Insts::Movsx::create(Func, Dest, Src0)); | 503 Context.insert<typename Traits::Insts::Movsx>(Dest, Src0); |
510 } | 504 } |
511 void _movzx(Variable *Dest, Operand *Src0) { | 505 void _movzx(Variable *Dest, Operand *Src0) { |
512 Context.insert(Traits::Insts::Movzx::create(Func, Dest, Src0)); | 506 Context.insert<typename Traits::Insts::Movzx>(Dest, Src0); |
513 } | 507 } |
514 void _maxss(Variable *Dest, Operand *Src0) { | 508 void _maxss(Variable *Dest, Operand *Src0) { |
515 Context.insert(Traits::Insts::Maxss::create(Func, Dest, Src0)); | 509 Context.insert<typename Traits::Insts::Maxss>(Dest, Src0); |
516 } | 510 } |
517 void _minss(Variable *Dest, Operand *Src0) { | 511 void _minss(Variable *Dest, Operand *Src0) { |
518 Context.insert(Traits::Insts::Minss::create(Func, Dest, Src0)); | 512 Context.insert<typename Traits::Insts::Minss>(Dest, Src0); |
519 } | 513 } |
520 void _mul(Variable *Dest, Variable *Src0, Operand *Src1) { | 514 void _mul(Variable *Dest, Variable *Src0, Operand *Src1) { |
521 Context.insert(Traits::Insts::Mul::create(Func, Dest, Src0, Src1)); | 515 Context.insert<typename Traits::Insts::Mul>(Dest, Src0, Src1); |
522 } | 516 } |
523 void _mulps(Variable *Dest, Operand *Src0) { | 517 void _mulps(Variable *Dest, Operand *Src0) { |
524 Context.insert(Traits::Insts::Mulps::create(Func, Dest, Src0)); | 518 Context.insert<typename Traits::Insts::Mulps>(Dest, Src0); |
525 } | 519 } |
526 void _mulss(Variable *Dest, Operand *Src0) { | 520 void _mulss(Variable *Dest, Operand *Src0) { |
527 Context.insert(Traits::Insts::Mulss::create(Func, Dest, Src0)); | 521 Context.insert<typename Traits::Insts::Mulss>(Dest, Src0); |
528 } | 522 } |
529 void _neg(Variable *SrcDest) { | 523 void _neg(Variable *SrcDest) { |
530 Context.insert(Traits::Insts::Neg::create(Func, SrcDest)); | 524 Context.insert<typename Traits::Insts::Neg>(SrcDest); |
531 } | 525 } |
532 void _nop(SizeT Variant) { | 526 void _nop(SizeT Variant) { |
533 Context.insert(Traits::Insts::Nop::create(Func, Variant)); | 527 Context.insert<typename Traits::Insts::Nop>(Variant); |
534 } | 528 } |
535 void _or(Variable *Dest, Operand *Src0) { | 529 void _or(Variable *Dest, Operand *Src0) { |
536 Context.insert(Traits::Insts::Or::create(Func, Dest, Src0)); | 530 Context.insert<typename Traits::Insts::Or>(Dest, Src0); |
537 } | 531 } |
538 void _orps(Variable *Dest, Operand *Src0) { | 532 void _orps(Variable *Dest, Operand *Src0) { |
539 Context.insert(Traits::Insts::Orps::create(Func, Dest, Src0)); | 533 Context.insert<typename Traits::Insts::Orps>(Dest, Src0); |
540 } | 534 } |
541 void _or_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { | 535 void _or_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { |
542 Context.insert(Traits::Insts::OrRMW::create(Func, DestSrc0, Src1)); | 536 Context.insert<typename Traits::Insts::OrRMW>(DestSrc0, Src1); |
543 } | 537 } |
544 void _padd(Variable *Dest, Operand *Src0) { | 538 void _padd(Variable *Dest, Operand *Src0) { |
545 Context.insert(Traits::Insts::Padd::create(Func, Dest, Src0)); | 539 Context.insert<typename Traits::Insts::Padd>(Dest, Src0); |
546 } | 540 } |
547 void _pand(Variable *Dest, Operand *Src0) { | 541 void _pand(Variable *Dest, Operand *Src0) { |
548 Context.insert(Traits::Insts::Pand::create(Func, Dest, Src0)); | 542 Context.insert<typename Traits::Insts::Pand>(Dest, Src0); |
549 } | 543 } |
550 void _pandn(Variable *Dest, Operand *Src0) { | 544 void _pandn(Variable *Dest, Operand *Src0) { |
551 Context.insert(Traits::Insts::Pandn::create(Func, Dest, Src0)); | 545 Context.insert<typename Traits::Insts::Pandn>(Dest, Src0); |
552 } | 546 } |
553 void _pblendvb(Variable *Dest, Operand *Src0, Operand *Src1) { | 547 void _pblendvb(Variable *Dest, Operand *Src0, Operand *Src1) { |
554 Context.insert(Traits::Insts::Pblendvb::create(Func, Dest, Src0, Src1)); | 548 Context.insert<typename Traits::Insts::Pblendvb>(Dest, Src0, Src1); |
555 } | 549 } |
556 void _pcmpeq(Variable *Dest, Operand *Src0) { | 550 void _pcmpeq(Variable *Dest, Operand *Src0) { |
557 Context.insert(Traits::Insts::Pcmpeq::create(Func, Dest, Src0)); | 551 Context.insert<typename Traits::Insts::Pcmpeq>(Dest, Src0); |
558 } | 552 } |
559 void _pcmpgt(Variable *Dest, Operand *Src0) { | 553 void _pcmpgt(Variable *Dest, Operand *Src0) { |
560 Context.insert(Traits::Insts::Pcmpgt::create(Func, Dest, Src0)); | 554 Context.insert<typename Traits::Insts::Pcmpgt>(Dest, Src0); |
561 } | 555 } |
562 void _pextr(Variable *Dest, Operand *Src0, Operand *Src1) { | 556 void _pextr(Variable *Dest, Operand *Src0, Operand *Src1) { |
563 Context.insert(Traits::Insts::Pextr::create(Func, Dest, Src0, Src1)); | 557 Context.insert<typename Traits::Insts::Pextr>(Dest, Src0, Src1); |
564 } | 558 } |
565 void _pinsr(Variable *Dest, Operand *Src0, Operand *Src1) { | 559 void _pinsr(Variable *Dest, Operand *Src0, Operand *Src1) { |
566 Context.insert(Traits::Insts::Pinsr::create(Func, Dest, Src0, Src1)); | 560 Context.insert<typename Traits::Insts::Pinsr>(Dest, Src0, Src1); |
567 } | 561 } |
568 void _pmull(Variable *Dest, Operand *Src0) { | 562 void _pmull(Variable *Dest, Operand *Src0) { |
569 Context.insert(Traits::Insts::Pmull::create(Func, Dest, Src0)); | 563 Context.insert<typename Traits::Insts::Pmull>(Dest, Src0); |
570 } | 564 } |
571 void _pmuludq(Variable *Dest, Operand *Src0) { | 565 void _pmuludq(Variable *Dest, Operand *Src0) { |
572 Context.insert(Traits::Insts::Pmuludq::create(Func, Dest, Src0)); | 566 Context.insert<typename Traits::Insts::Pmuludq>(Dest, Src0); |
573 } | 567 } |
574 void _pop(Variable *Dest) { | 568 void _pop(Variable *Dest) { |
575 Context.insert(Traits::Insts::Pop::create(Func, Dest)); | 569 Context.insert<typename Traits::Insts::Pop>(Dest); |
576 } | 570 } |
577 void _por(Variable *Dest, Operand *Src0) { | 571 void _por(Variable *Dest, Operand *Src0) { |
578 Context.insert(Traits::Insts::Por::create(Func, Dest, Src0)); | 572 Context.insert<typename Traits::Insts::Por>(Dest, Src0); |
579 } | 573 } |
580 void _pshufd(Variable *Dest, Operand *Src0, Operand *Src1) { | 574 void _pshufd(Variable *Dest, Operand *Src0, Operand *Src1) { |
581 Context.insert(Traits::Insts::Pshufd::create(Func, Dest, Src0, Src1)); | 575 Context.insert<typename Traits::Insts::Pshufd>(Dest, Src0, Src1); |
582 } | 576 } |
583 void _psll(Variable *Dest, Operand *Src0) { | 577 void _psll(Variable *Dest, Operand *Src0) { |
584 Context.insert(Traits::Insts::Psll::create(Func, Dest, Src0)); | 578 Context.insert<typename Traits::Insts::Psll>(Dest, Src0); |
585 } | 579 } |
586 void _psra(Variable *Dest, Operand *Src0) { | 580 void _psra(Variable *Dest, Operand *Src0) { |
587 Context.insert(Traits::Insts::Psra::create(Func, Dest, Src0)); | 581 Context.insert<typename Traits::Insts::Psra>(Dest, Src0); |
588 } | 582 } |
589 void _psrl(Variable *Dest, Operand *Src0) { | 583 void _psrl(Variable *Dest, Operand *Src0) { |
590 Context.insert(Traits::Insts::Psrl::create(Func, Dest, Src0)); | 584 Context.insert<typename Traits::Insts::Psrl>(Dest, Src0); |
591 } | 585 } |
592 void _psub(Variable *Dest, Operand *Src0) { | 586 void _psub(Variable *Dest, Operand *Src0) { |
593 Context.insert(Traits::Insts::Psub::create(Func, Dest, Src0)); | 587 Context.insert<typename Traits::Insts::Psub>(Dest, Src0); |
594 } | 588 } |
595 void _push(Variable *Src0) { | 589 void _push(Variable *Src0) { |
596 Context.insert(Traits::Insts::Push::create(Func, Src0)); | 590 Context.insert<typename Traits::Insts::Push>(Src0); |
597 } | 591 } |
598 void _pxor(Variable *Dest, Operand *Src0) { | 592 void _pxor(Variable *Dest, Operand *Src0) { |
599 Context.insert(Traits::Insts::Pxor::create(Func, Dest, Src0)); | 593 Context.insert<typename Traits::Insts::Pxor>(Dest, Src0); |
600 } | 594 } |
601 void _ret(Variable *Src0 = nullptr) { | 595 void _ret(Variable *Src0 = nullptr) { |
602 Context.insert(Traits::Insts::Ret::create(Func, Src0)); | 596 Context.insert<typename Traits::Insts::Ret>(Src0); |
603 } | 597 } |
604 void _rol(Variable *Dest, Operand *Src0) { | 598 void _rol(Variable *Dest, Operand *Src0) { |
605 Context.insert(Traits::Insts::Rol::create(Func, Dest, Src0)); | 599 Context.insert<typename Traits::Insts::Rol>(Dest, Src0); |
606 } | 600 } |
607 void _sar(Variable *Dest, Operand *Src0) { | 601 void _sar(Variable *Dest, Operand *Src0) { |
608 Context.insert(Traits::Insts::Sar::create(Func, Dest, Src0)); | 602 Context.insert<typename Traits::Insts::Sar>(Dest, Src0); |
609 } | 603 } |
610 void _sbb(Variable *Dest, Operand *Src0) { | 604 void _sbb(Variable *Dest, Operand *Src0) { |
611 Context.insert(Traits::Insts::Sbb::create(Func, Dest, Src0)); | 605 Context.insert<typename Traits::Insts::Sbb>(Dest, Src0); |
612 } | 606 } |
613 void _sbb_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { | 607 void _sbb_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { |
614 Context.insert(Traits::Insts::SbbRMW::create(Func, DestSrc0, Src1)); | 608 Context.insert<typename Traits::Insts::SbbRMW>(DestSrc0, Src1); |
615 } | 609 } |
616 void _setcc(Variable *Dest, typename Traits::Cond::BrCond Condition) { | 610 void _setcc(Variable *Dest, typename Traits::Cond::BrCond Condition) { |
617 Context.insert(Traits::Insts::Setcc::create(Func, Dest, Condition)); | 611 Context.insert<typename Traits::Insts::Setcc>(Dest, Condition); |
618 } | 612 } |
619 void _shl(Variable *Dest, Operand *Src0) { | 613 void _shl(Variable *Dest, Operand *Src0) { |
620 Context.insert(Traits::Insts::Shl::create(Func, Dest, Src0)); | 614 Context.insert<typename Traits::Insts::Shl>(Dest, Src0); |
621 } | 615 } |
622 void _shld(Variable *Dest, Variable *Src0, Operand *Src1) { | 616 void _shld(Variable *Dest, Variable *Src0, Operand *Src1) { |
623 Context.insert(Traits::Insts::Shld::create(Func, Dest, Src0, Src1)); | 617 Context.insert<typename Traits::Insts::Shld>(Dest, Src0, Src1); |
624 } | 618 } |
625 void _shr(Variable *Dest, Operand *Src0) { | 619 void _shr(Variable *Dest, Operand *Src0) { |
626 Context.insert(Traits::Insts::Shr::create(Func, Dest, Src0)); | 620 Context.insert<typename Traits::Insts::Shr>(Dest, Src0); |
627 } | 621 } |
628 void _shrd(Variable *Dest, Variable *Src0, Operand *Src1) { | 622 void _shrd(Variable *Dest, Variable *Src0, Operand *Src1) { |
629 Context.insert(Traits::Insts::Shrd::create(Func, Dest, Src0, Src1)); | 623 Context.insert<typename Traits::Insts::Shrd>(Dest, Src0, Src1); |
630 } | 624 } |
631 void _shufps(Variable *Dest, Operand *Src0, Operand *Src1) { | 625 void _shufps(Variable *Dest, Operand *Src0, Operand *Src1) { |
632 Context.insert(Traits::Insts::Shufps::create(Func, Dest, Src0, Src1)); | 626 Context.insert<typename Traits::Insts::Shufps>(Dest, Src0, Src1); |
633 } | 627 } |
634 void _sqrtss(Variable *Dest, Operand *Src0) { | 628 void _sqrtss(Variable *Dest, Operand *Src0) { |
635 Context.insert(Traits::Insts::Sqrtss::create(Func, Dest, Src0)); | 629 Context.insert<typename Traits::Insts::Sqrtss>(Dest, Src0); |
636 } | 630 } |
637 void _store(Operand *Value, typename Traits::X86Operand *Mem) { | 631 void _store(Operand *Value, typename Traits::X86Operand *Mem) { |
638 Context.insert(Traits::Insts::Store::create(Func, Value, Mem)); | 632 Context.insert<typename Traits::Insts::Store>(Value, Mem); |
639 } | 633 } |
640 void _storep(Variable *Value, typename Traits::X86OperandMem *Mem) { | 634 void _storep(Variable *Value, typename Traits::X86OperandMem *Mem) { |
641 Context.insert(Traits::Insts::StoreP::create(Func, Value, Mem)); | 635 Context.insert<typename Traits::Insts::StoreP>(Value, Mem); |
642 } | 636 } |
643 void _storeq(Variable *Value, typename Traits::X86OperandMem *Mem) { | 637 void _storeq(Variable *Value, typename Traits::X86OperandMem *Mem) { |
644 Context.insert(Traits::Insts::StoreQ::create(Func, Value, Mem)); | 638 Context.insert<typename Traits::Insts::StoreQ>(Value, Mem); |
645 } | 639 } |
646 void _sub(Variable *Dest, Operand *Src0) { | 640 void _sub(Variable *Dest, Operand *Src0) { |
647 Context.insert(Traits::Insts::Sub::create(Func, Dest, Src0)); | 641 Context.insert<typename Traits::Insts::Sub>(Dest, Src0); |
648 } | 642 } |
649 void _sub_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { | 643 void _sub_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { |
650 Context.insert(Traits::Insts::SubRMW::create(Func, DestSrc0, Src1)); | 644 Context.insert<typename Traits::Insts::SubRMW>(DestSrc0, Src1); |
651 } | 645 } |
652 void _subps(Variable *Dest, Operand *Src0) { | 646 void _subps(Variable *Dest, Operand *Src0) { |
653 Context.insert(Traits::Insts::Subps::create(Func, Dest, Src0)); | 647 Context.insert<typename Traits::Insts::Subps>(Dest, Src0); |
654 } | 648 } |
655 void _subss(Variable *Dest, Operand *Src0) { | 649 void _subss(Variable *Dest, Operand *Src0) { |
656 Context.insert(Traits::Insts::Subss::create(Func, Dest, Src0)); | 650 Context.insert<typename Traits::Insts::Subss>(Dest, Src0); |
657 } | 651 } |
658 void _test(Operand *Src0, Operand *Src1) { | 652 void _test(Operand *Src0, Operand *Src1) { |
659 Context.insert(Traits::Insts::Test::create(Func, Src0, Src1)); | 653 Context.insert<typename Traits::Insts::Test>(Src0, Src1); |
660 } | 654 } |
661 void _ucomiss(Operand *Src0, Operand *Src1) { | 655 void _ucomiss(Operand *Src0, Operand *Src1) { |
662 Context.insert(Traits::Insts::Ucomiss::create(Func, Src0, Src1)); | 656 Context.insert<typename Traits::Insts::Ucomiss>(Src0, Src1); |
663 } | 657 } |
664 void _ud2() { Context.insert(Traits::Insts::UD2::create(Func)); } | 658 void _ud2() { Context.insert<typename Traits::Insts::UD2>(); } |
665 void _xadd(Operand *Dest, Variable *Src, bool Locked) { | 659 void _xadd(Operand *Dest, Variable *Src, bool Locked) { |
666 Context.insert(Traits::Insts::Xadd::create(Func, Dest, Src, Locked)); | 660 Context.insert<typename Traits::Insts::Xadd>(Dest, Src, Locked); |
667 // The xadd exchanges Dest and Src (modifying Src). Model that update with | 661 // The xadd exchanges Dest and Src (modifying Src). Model that update with |
668 // a FakeDef followed by a FakeUse. | 662 // a FakeDef followed by a FakeUse. |
669 Context.insert( | 663 Context.insert<InstFakeDef>(Src, llvm::dyn_cast<Variable>(Dest)); |
670 InstFakeDef::create(Func, Src, llvm::dyn_cast<Variable>(Dest))); | |
671 _set_dest_redefined(); | 664 _set_dest_redefined(); |
672 Context.insert(InstFakeUse::create(Func, Src)); | 665 Context.insert<InstFakeUse>(Src); |
673 } | 666 } |
674 void _xchg(Operand *Dest, Variable *Src) { | 667 void _xchg(Operand *Dest, Variable *Src) { |
675 Context.insert(Traits::Insts::Xchg::create(Func, Dest, Src)); | 668 Context.insert<typename Traits::Insts::Xchg>(Dest, Src); |
676 // The xchg modifies Dest and Src -- model that update with a | 669 // The xchg modifies Dest and Src -- model that update with a |
677 // FakeDef/FakeUse. | 670 // FakeDef/FakeUse. |
678 Context.insert( | 671 Context.insert<InstFakeDef>(Src, llvm::dyn_cast<Variable>(Dest)); |
679 InstFakeDef::create(Func, Src, llvm::dyn_cast<Variable>(Dest))); | |
680 _set_dest_redefined(); | 672 _set_dest_redefined(); |
681 Context.insert(InstFakeUse::create(Func, Src)); | 673 Context.insert<InstFakeUse>(Src); |
682 } | 674 } |
683 void _xor(Variable *Dest, Operand *Src0) { | 675 void _xor(Variable *Dest, Operand *Src0) { |
684 Context.insert(Traits::Insts::Xor::create(Func, Dest, Src0)); | 676 Context.insert<typename Traits::Insts::Xor>(Dest, Src0); |
685 } | 677 } |
686 void _xorps(Variable *Dest, Operand *Src0) { | 678 void _xorps(Variable *Dest, Operand *Src0) { |
687 Context.insert(Traits::Insts::Xorps::create(Func, Dest, Src0)); | 679 Context.insert<typename Traits::Insts::Xorps>(Dest, Src0); |
688 } | 680 } |
689 void _xor_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { | 681 void _xor_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { |
690 Context.insert(Traits::Insts::XorRMW::create(Func, DestSrc0, Src1)); | 682 Context.insert<typename Traits::Insts::XorRMW>(DestSrc0, Src1); |
691 } | 683 } |
692 | 684 |
693 void _iaca_start() { | 685 void _iaca_start() { |
694 if (!BuildDefs::minimal()) | 686 if (!BuildDefs::minimal()) |
695 Context.insert(Traits::Insts::IacaStart::create(Func)); | 687 Context.insert<typename Traits::Insts::IacaStart>(); |
696 } | 688 } |
697 void _iaca_end() { | 689 void _iaca_end() { |
698 if (!BuildDefs::minimal()) | 690 if (!BuildDefs::minimal()) |
699 Context.insert(Traits::Insts::IacaEnd::create(Func)); | 691 Context.insert<typename Traits::Insts::IacaEnd>(); |
700 } | 692 } |
701 | 693 |
702 /// This class helps wrap IACA markers around the code generated by the | 694 /// This class helps wrap IACA markers around the code generated by the |
703 /// current scope. It means you don't need to put an end before each return. | 695 /// current scope. It means you don't need to put an end before each return. |
704 class ScopedIacaMark { | 696 class ScopedIacaMark { |
705 ScopedIacaMark(const ScopedIacaMark &) = delete; | 697 ScopedIacaMark(const ScopedIacaMark &) = delete; |
706 ScopedIacaMark &operator=(const ScopedIacaMark &) = delete; | 698 ScopedIacaMark &operator=(const ScopedIacaMark &) = delete; |
707 | 699 |
708 public: | 700 public: |
709 ScopedIacaMark(TargetX86Base *Lowering) : Lowering(Lowering) { | 701 ScopedIacaMark(TargetX86Base *Lowering) : Lowering(Lowering) { |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
819 lowerIcmp64(const InstIcmp *Icmp, const Inst *Consumer); | 811 lowerIcmp64(const InstIcmp *Icmp, const Inst *Consumer); |
820 | 812 |
821 BoolFolding FoldingInfo; | 813 BoolFolding FoldingInfo; |
822 }; | 814 }; |
823 } // end of namespace X86Internal | 815 } // end of namespace X86Internal |
824 } // end of namespace Ice | 816 } // end of namespace Ice |
825 | 817 |
826 #include "IceTargetLoweringX86BaseImpl.h" | 818 #include "IceTargetLoweringX86BaseImpl.h" |
827 | 819 |
828 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASE_H | 820 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASE_H |
OLD | NEW |