| 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 |