Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- subzero/src/IceInstX86BaseImpl.h - Generic X86 instructions -*- C++ -*=// | 1 //===- subzero/src/IceInstX86BaseImpl.h - Generic X86 instructions -*- 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 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 199 this->addSource(Source); | 199 this->addSource(Source); |
| 200 } | 200 } |
| 201 | 201 |
| 202 template <class Machine> | 202 template <class Machine> |
| 203 InstX86Cmpxchg<Machine>::InstX86Cmpxchg(Cfg *Func, Operand *DestOrAddr, | 203 InstX86Cmpxchg<Machine>::InstX86Cmpxchg(Cfg *Func, Operand *DestOrAddr, |
| 204 Variable *Eax, Variable *Desired, | 204 Variable *Eax, Variable *Desired, |
| 205 bool Locked) | 205 bool Locked) |
| 206 : InstX86BaseLockable<Machine>(Func, InstX86Base<Machine>::Cmpxchg, 3, | 206 : InstX86BaseLockable<Machine>(Func, InstX86Base<Machine>::Cmpxchg, 3, |
| 207 llvm::dyn_cast<Variable>(DestOrAddr), | 207 llvm::dyn_cast<Variable>(DestOrAddr), |
| 208 Locked) { | 208 Locked) { |
| 209 assert(Eax->getRegNum() == | 209 assert(InstX86Base<Machine>::Traits::getBaseReg(Eax->getRegNum()) == |
| 210 InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); | 210 InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); |
| 211 this->addSource(DestOrAddr); | 211 this->addSource(DestOrAddr); |
| 212 this->addSource(Eax); | 212 this->addSource(Eax); |
| 213 this->addSource(Desired); | 213 this->addSource(Desired); |
| 214 } | 214 } |
| 215 | 215 |
| 216 template <class Machine> | 216 template <class Machine> |
| 217 InstX86Cmpxchg8b<Machine>::InstX86Cmpxchg8b( | 217 InstX86Cmpxchg8b<Machine>::InstX86Cmpxchg8b( |
| 218 Cfg *Func, typename InstX86Base<Machine>::Traits::X86OperandMem *Addr, | 218 Cfg *Func, typename InstX86Base<Machine>::Traits::X86OperandMem *Addr, |
| 219 Variable *Edx, Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked) | 219 Variable *Edx, Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked) |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 514 Str << "\tjmp\t*"; | 514 Str << "\tjmp\t*"; |
| 515 getJmpTarget()->emit(Func); | 515 getJmpTarget()->emit(Func); |
| 516 } | 516 } |
| 517 | 517 |
| 518 template <class Machine> | 518 template <class Machine> |
| 519 void InstX86Jmp<Machine>::emitIAS(const Cfg *Func) const { | 519 void InstX86Jmp<Machine>::emitIAS(const Cfg *Func) const { |
| 520 // Note: Adapted (mostly copied) from InstX86Call<Machine>::emitIAS(). | 520 // Note: Adapted (mostly copied) from InstX86Call<Machine>::emitIAS(). |
| 521 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 521 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 522 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 522 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 523 Operand *Target = getJmpTarget(); | 523 Operand *Target = getJmpTarget(); |
| 524 if (const auto Var = llvm::dyn_cast<Variable>(Target)) { | 524 if (const auto *Var = llvm::dyn_cast<Variable>(Target)) { |
| 525 if (Var->hasReg()) { | 525 if (Var->hasReg()) { |
| 526 Asm->jmp(InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | 526 Asm->jmp(InstX86Base<Machine>::Traits::getEncodedGPR(Var->getRegNum())); |
| 527 Var->getRegNum())); | |
| 528 } else { | 527 } else { |
| 529 // The jmp instruction with a memory operand should be possible to | 528 // The jmp instruction with a memory operand should be possible to |
| 530 // encode, but it isn't a valid sandboxed instruction, and there | 529 // encode, but it isn't a valid sandboxed instruction, and there |
| 531 // shouldn't be a register allocation issue to jump through a scratch | 530 // shouldn't be a register allocation issue to jump through a scratch |
| 532 // register, so we don't really need to bother implementing it. | 531 // register, so we don't really need to bother implementing it. |
| 533 llvm::report_fatal_error("Assembler can't jmp to memory operand"); | 532 llvm::report_fatal_error("Assembler can't jmp to memory operand"); |
| 534 } | 533 } |
| 535 } else if (const auto Mem = llvm::dyn_cast< | 534 } else if (const auto *Mem = llvm::dyn_cast< |
| 536 typename InstX86Base<Machine>::Traits::X86OperandMem>( | 535 typename InstX86Base<Machine>::Traits::X86OperandMem>( |
| 537 Target)) { | 536 Target)) { |
| 538 (void)Mem; | 537 (void)Mem; |
| 539 assert(Mem->getSegmentRegister() == | 538 assert(Mem->getSegmentRegister() == |
| 540 InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment); | 539 InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment); |
| 541 llvm::report_fatal_error("Assembler can't jmp to memory operand"); | 540 llvm::report_fatal_error("Assembler can't jmp to memory operand"); |
| 542 } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Target)) { | 541 } else if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(Target)) { |
| 543 assert(CR->getOffset() == 0 && "We only support jumping to a function"); | 542 assert(CR->getOffset() == 0 && "We only support jumping to a function"); |
| 544 Asm->jmp(CR); | 543 Asm->jmp(CR); |
| 545 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Target)) { | 544 } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Target)) { |
| 546 // NaCl trampoline calls refer to an address within the sandbox directly. | 545 // NaCl trampoline calls refer to an address within the sandbox directly. |
| 547 // This is usually only needed for non-IRT builds and otherwise not very | 546 // This is usually only needed for non-IRT builds and otherwise not very |
| 548 // portable or stable. Usually this is only done for "calls" and not jumps. | 547 // portable or stable. Usually this is only done for "calls" and not jumps. |
| 549 // TODO(jvoung): Support this when there is a lowering that actually | 548 // TODO(jvoung): Support this when there is a lowering that actually |
| 550 // triggers this case. | 549 // triggers this case. |
| 551 (void)Imm; | 550 (void)Imm; |
| 552 llvm::report_fatal_error("Unexpected jmp to absolute address"); | 551 llvm::report_fatal_error("Unexpected jmp to absolute address"); |
| 553 } else { | 552 } else { |
| 554 llvm::report_fatal_error("Unexpected operand type"); | 553 llvm::report_fatal_error("Unexpected operand type"); |
| 555 } | 554 } |
| 556 } | 555 } |
| 557 | 556 |
| 558 template <class Machine> void InstX86Jmp<Machine>::dump(const Cfg *Func) const { | 557 template <class Machine> void InstX86Jmp<Machine>::dump(const Cfg *Func) const { |
| 559 if (!BuildDefs::dump()) | 558 if (!BuildDefs::dump()) |
| 560 return; | 559 return; |
| 561 Ostream &Str = Func->getContext()->getStrDump(); | 560 Ostream &Str = Func->getContext()->getStrDump(); |
| 562 Str << "jmp "; | 561 Str << "jmp "; |
| 563 getJmpTarget()->dump(Func); | 562 getJmpTarget()->dump(Func); |
| 564 } | 563 } |
| 565 | 564 |
| 566 template <class Machine> | 565 template <class Machine> |
| 567 void InstX86Call<Machine>::emit(const Cfg *Func) const { | 566 void InstX86Call<Machine>::emit(const Cfg *Func) const { |
| 568 if (!BuildDefs::dump()) | 567 if (!BuildDefs::dump()) |
| 569 return; | 568 return; |
| 570 Ostream &Str = Func->getContext()->getStrEmit(); | 569 Ostream &Str = Func->getContext()->getStrEmit(); |
| 571 assert(this->getSrcSize() == 1); | 570 assert(this->getSrcSize() == 1); |
| 572 Str << "\tcall\t"; | 571 Str << "\tcall\t"; |
| 573 if (const auto CI = llvm::dyn_cast<ConstantInteger32>(getCallTarget())) { | 572 if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getCallTarget())) { |
| 574 // Emit without a leading '$'. | 573 // Emit without a leading '$'. |
| 575 Str << CI->getValue(); | 574 Str << CI->getValue(); |
| 576 } else if (const auto CallTarget = | 575 } else if (const auto CallTarget = |
| 577 llvm::dyn_cast<ConstantRelocatable>(getCallTarget())) { | 576 llvm::dyn_cast<ConstantRelocatable>(getCallTarget())) { |
| 578 CallTarget->emitWithoutPrefix(Func->getTarget()); | 577 CallTarget->emitWithoutPrefix(Func->getTarget()); |
| 579 } else { | 578 } else { |
| 580 Str << "*"; | 579 Str << "*"; |
| 581 getCallTarget()->emit(Func); | 580 getCallTarget()->emit(Func); |
| 582 } | 581 } |
| 583 Func->getTarget()->resetStackAdjustment(); | 582 Func->getTarget()->resetStackAdjustment(); |
| 584 } | 583 } |
| 585 | 584 |
| 586 template <class Machine> | 585 template <class Machine> |
| 587 void InstX86Call<Machine>::emitIAS(const Cfg *Func) const { | 586 void InstX86Call<Machine>::emitIAS(const Cfg *Func) const { |
| 588 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 587 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 589 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 588 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 590 Operand *Target = getCallTarget(); | 589 Operand *Target = getCallTarget(); |
| 591 if (const auto Var = llvm::dyn_cast<Variable>(Target)) { | 590 if (const auto *Var = llvm::dyn_cast<Variable>(Target)) { |
| 592 if (Var->hasReg()) { | 591 if (Var->hasReg()) { |
| 593 Asm->call(InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | 592 Asm->call(InstX86Base<Machine>::Traits::getEncodedGPR(Var->getRegNum())); |
| 594 Var->getRegNum())); | |
| 595 } else { | 593 } else { |
| 596 Asm->call( | 594 Asm->call( |
| 597 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 595 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 598 Func->getTarget()) | 596 Func->getTarget()) |
| 599 ->stackVarToAsmOperand(Var)); | 597 ->stackVarToAsmOperand(Var)); |
| 600 } | 598 } |
| 601 } else if (const auto Mem = llvm::dyn_cast< | 599 } else if (const auto *Mem = llvm::dyn_cast< |
| 602 typename InstX86Base<Machine>::Traits::X86OperandMem>( | 600 typename InstX86Base<Machine>::Traits::X86OperandMem>( |
| 603 Target)) { | 601 Target)) { |
| 604 assert(Mem->getSegmentRegister() == | 602 assert(Mem->getSegmentRegister() == |
| 605 InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment); | 603 InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment); |
| 606 Asm->call(Mem->toAsmAddress(Asm)); | 604 Asm->call(Mem->toAsmAddress(Asm)); |
| 607 } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Target)) { | 605 } else if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(Target)) { |
| 608 assert(CR->getOffset() == 0 && "We only support calling a function"); | 606 assert(CR->getOffset() == 0 && "We only support calling a function"); |
| 609 Asm->call(CR); | 607 Asm->call(CR); |
| 610 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Target)) { | 608 } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Target)) { |
| 611 Asm->call(Immediate(Imm->getValue())); | 609 Asm->call(Immediate(Imm->getValue())); |
| 612 } else { | 610 } else { |
| 613 llvm_unreachable("Unexpected operand type"); | 611 llvm_unreachable("Unexpected operand type"); |
| 614 } | 612 } |
| 615 Func->getTarget()->resetStackAdjustment(); | 613 Func->getTarget()->resetStackAdjustment(); |
| 616 } | 614 } |
| 617 | 615 |
| 618 template <class Machine> | 616 template <class Machine> |
| 619 void InstX86Call<Machine>::dump(const Cfg *Func) const { | 617 void InstX86Call<Machine>::dump(const Cfg *Func) const { |
| 620 if (!BuildDefs::dump()) | 618 if (!BuildDefs::dump()) |
| 621 return; | 619 return; |
| 622 Ostream &Str = Func->getContext()->getStrDump(); | 620 Ostream &Str = Func->getContext()->getStrDump(); |
| 623 if (this->getDest()) { | 621 if (this->getDest()) { |
| 624 this->dumpDest(Func); | 622 this->dumpDest(Func); |
| 625 Str << " = "; | 623 Str << " = "; |
| 626 } | 624 } |
| 627 Str << "call "; | 625 Str << "call "; |
| 628 getCallTarget()->dump(Func); | 626 getCallTarget()->dump(Func); |
| 629 } | 627 } |
| 630 | 628 |
| 631 // The ShiftHack parameter is used to emit "cl" instead of "ecx" for shift | 629 // The this->Opcode parameter needs to be char* and not IceString because of |
| 632 // instructions, in order to be syntactically valid. The this->Opcode parameter | 630 // template issues. |
| 633 // needs to be char* and not IceString because of template issues. | |
| 634 template <class Machine> | 631 template <class Machine> |
| 635 void InstX86Base<Machine>::emitTwoAddress(const char *Opcode, const Inst *Inst, | 632 void InstX86Base<Machine>::emitTwoAddress(const char *Opcode, const Inst *Inst, |
| 636 const Cfg *Func, bool ShiftHack) { | 633 const Cfg *Func) { |
| 637 if (!BuildDefs::dump()) | 634 if (!BuildDefs::dump()) |
| 638 return; | 635 return; |
| 639 Ostream &Str = Func->getContext()->getStrEmit(); | 636 Ostream &Str = Func->getContext()->getStrEmit(); |
| 640 assert(Inst->getSrcSize() == 2); | 637 assert(Inst->getSrcSize() == 2); |
| 641 Operand *Dest = Inst->getDest(); | 638 Operand *Dest = Inst->getDest(); |
| 642 if (Dest == nullptr) | 639 if (Dest == nullptr) |
| 643 Dest = Inst->getSrc(0); | 640 Dest = Inst->getSrc(0); |
| 644 assert(Dest == Inst->getSrc(0)); | 641 assert(Dest == Inst->getSrc(0)); |
| 645 Operand *Src1 = Inst->getSrc(1); | 642 Operand *Src1 = Inst->getSrc(1); |
| 646 Str << "\t" << Opcode << InstX86Base<Machine>::getWidthString(Dest->getType()) | 643 Str << "\t" << Opcode << InstX86Base<Machine>::getWidthString(Dest->getType()) |
| 647 << "\t"; | 644 << "\t"; |
| 648 const auto ShiftReg = llvm::dyn_cast<Variable>(Src1); | 645 Src1->emit(Func); |
| 649 if (ShiftHack && ShiftReg && | |
|
John
2015/10/28 12:48:06
I don't know if this will work for X8664, but I'll
Jim Stichnoth
2015/10/28 14:03:55
I think this particular thing ought to work for x8
| |
| 650 ShiftReg->getRegNum() == | |
| 651 InstX86Base<Machine>::Traits::RegisterSet::Reg_ecx) | |
| 652 Str << "%cl"; | |
| 653 else | |
| 654 Src1->emit(Func); | |
| 655 Str << ", "; | 646 Str << ", "; |
| 656 Dest->emit(Func); | 647 Dest->emit(Func); |
| 657 } | 648 } |
| 658 | 649 |
| 659 template <class Machine> | 650 template <class Machine> |
| 660 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op, | 651 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op, |
| 661 const typename InstX86Base< | 652 const typename InstX86Base< |
| 662 Machine>::Traits::Assembler::GPREmitterOneOp &Emitter) { | 653 Machine>::Traits::Assembler::GPREmitterOneOp &Emitter) { |
| 663 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 654 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 664 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 655 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 665 if (const auto Var = llvm::dyn_cast<Variable>(Op)) { | 656 if (const auto *Var = llvm::dyn_cast<Variable>(Op)) { |
| 666 if (Var->hasReg()) { | 657 if (Var->hasReg()) { |
| 667 // We cheat a little and use GPRRegister even for byte operations. | 658 // We cheat a little and use GPRRegister even for byte operations. |
| 668 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister VarReg = | 659 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister VarReg = |
| 669 InstX86Base<Machine>::Traits::RegisterSet::getEncodedByteRegOrGPR( | 660 InstX86Base<Machine>::Traits::getEncodedGPR(Var->getRegNum()); |
| 670 Ty, Var->getRegNum()); | |
| 671 (Asm->*(Emitter.Reg))(Ty, VarReg); | 661 (Asm->*(Emitter.Reg))(Ty, VarReg); |
| 672 } else { | 662 } else { |
| 673 typename InstX86Base<Machine>::Traits::Address StackAddr( | 663 typename InstX86Base<Machine>::Traits::Address StackAddr( |
| 674 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 664 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 675 Func->getTarget()) | 665 Func->getTarget()) |
| 676 ->stackVarToAsmOperand(Var)); | 666 ->stackVarToAsmOperand(Var)); |
| 677 (Asm->*(Emitter.Addr))(Ty, StackAddr); | 667 (Asm->*(Emitter.Addr))(Ty, StackAddr); |
| 678 } | 668 } |
| 679 } else if (const auto Mem = llvm::dyn_cast< | 669 } else if (const auto *Mem = llvm::dyn_cast< |
| 680 typename InstX86Base<Machine>::Traits::X86OperandMem>(Op)) { | 670 typename InstX86Base<Machine>::Traits::X86OperandMem>(Op)) { |
| 681 Mem->emitSegmentOverride(Asm); | 671 Mem->emitSegmentOverride(Asm); |
| 682 (Asm->*(Emitter.Addr))(Ty, Mem->toAsmAddress(Asm)); | 672 (Asm->*(Emitter.Addr))(Ty, Mem->toAsmAddress(Asm)); |
| 683 } else { | 673 } else { |
| 684 llvm_unreachable("Unexpected operand type"); | 674 llvm_unreachable("Unexpected operand type"); |
| 685 } | 675 } |
| 686 } | 676 } |
| 687 | 677 |
| 688 template <class Machine, bool VarCanBeByte, bool SrcCanBeByte> | 678 template <class Machine, bool VarCanBeByte, bool SrcCanBeByte> |
| 689 void emitIASRegOpTyGPR( | 679 void emitIASRegOpTyGPR( |
| 690 const Cfg *Func, Type Ty, const Variable *Var, const Operand *Src, | 680 const Cfg *Func, Type Ty, const Variable *Var, const Operand *Src, |
| 691 const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp | 681 const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp |
| 692 &Emitter) { | 682 &Emitter) { |
| 693 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 683 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 694 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 684 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 695 assert(Var->hasReg()); | 685 assert(Var->hasReg()); |
| 696 // We cheat a little and use GPRRegister even for byte operations. | 686 // We cheat a little and use GPRRegister even for byte operations. |
| 697 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister VarReg = | 687 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister VarReg = |
| 698 VarCanBeByte | 688 VarCanBeByte |
| 699 ? InstX86Base<Machine>::Traits::RegisterSet::getEncodedByteRegOrGPR( | 689 ? InstX86Base<Machine>::Traits::getEncodedGPR(Var->getRegNum()) |
| 700 Ty, Var->getRegNum()) | 690 : InstX86Base<Machine>::Traits::getEncodedGPR(Var->getRegNum()); |
| 701 : InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | 691 if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 702 Var->getRegNum()); | |
| 703 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | |
| 704 if (SrcVar->hasReg()) { | 692 if (SrcVar->hasReg()) { |
| 705 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg = | 693 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg = |
| 706 SrcCanBeByte | 694 SrcCanBeByte |
| 707 ? InstX86Base<Machine>::Traits::RegisterSet:: | 695 ? InstX86Base<Machine>::Traits::getEncodedGPR(SrcVar->getRegNum()) |
| 708 getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()) | 696 : InstX86Base<Machine>::Traits::getEncodedGPR( |
| 709 : InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | |
| 710 SrcVar->getRegNum()); | 697 SrcVar->getRegNum()); |
| 711 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg); | 698 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg); |
| 712 } else { | 699 } else { |
| 713 typename InstX86Base<Machine>::Traits::Address SrcStackAddr = | 700 typename InstX86Base<Machine>::Traits::Address SrcStackAddr = |
| 714 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 701 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 715 Func->getTarget()) | 702 Func->getTarget()) |
| 716 ->stackVarToAsmOperand(SrcVar); | 703 ->stackVarToAsmOperand(SrcVar); |
| 717 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr); | 704 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr); |
| 718 } | 705 } |
| 719 } else if (const auto Mem = llvm::dyn_cast< | 706 } else if (const auto *Mem = llvm::dyn_cast< |
| 720 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) { | 707 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) { |
| 721 Mem->emitSegmentOverride(Asm); | 708 Mem->emitSegmentOverride(Asm); |
| 722 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); | 709 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); |
| 723 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { | 710 } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
| 724 (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Imm->getValue())); | 711 (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Imm->getValue())); |
| 725 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { | 712 } else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { |
| 726 AssemblerFixup *Fixup = | 713 AssemblerFixup *Fixup = |
| 727 Asm->createFixup(InstX86Base<Machine>::Traits::RelFixup, Reloc); | 714 Asm->createFixup(InstX86Base<Machine>::Traits::RelFixup, Reloc); |
| 728 (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Reloc->getOffset(), Fixup)); | 715 (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Reloc->getOffset(), Fixup)); |
| 729 } else if (const auto Split = llvm::dyn_cast< | 716 } else if (const auto *Split = llvm::dyn_cast< |
| 730 typename InstX86Base<Machine>::Traits::VariableSplit>(Src)) { | 717 typename InstX86Base<Machine>::Traits::VariableSplit>(Src)) { |
| 731 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func)); | 718 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func)); |
| 732 } else { | 719 } else { |
| 733 llvm_unreachable("Unexpected operand type"); | 720 llvm_unreachable("Unexpected operand type"); |
| 734 } | 721 } |
| 735 } | 722 } |
| 736 | 723 |
| 737 template <class Machine> | 724 template <class Machine> |
| 738 void emitIASAddrOpTyGPR( | 725 void emitIASAddrOpTyGPR( |
| 739 const Cfg *Func, Type Ty, | 726 const Cfg *Func, Type Ty, |
| 740 const typename InstX86Base<Machine>::Traits::Address &Addr, | 727 const typename InstX86Base<Machine>::Traits::Address &Addr, |
| 741 const Operand *Src, | 728 const Operand *Src, |
| 742 const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp | 729 const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp |
| 743 &Emitter) { | 730 &Emitter) { |
| 744 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 731 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 745 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 732 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 746 // Src can only be Reg or Immediate. | 733 // Src can only be Reg or Immediate. |
| 747 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | 734 if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 748 assert(SrcVar->hasReg()); | 735 assert(SrcVar->hasReg()); |
| 749 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg = | 736 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg = |
| 750 InstX86Base<Machine>::Traits::RegisterSet::getEncodedByteRegOrGPR( | 737 InstX86Base<Machine>::Traits::getEncodedGPR(SrcVar->getRegNum()); |
| 751 Ty, SrcVar->getRegNum()); | |
| 752 (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg); | 738 (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg); |
| 753 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { | 739 } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
| 754 (Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Imm->getValue())); | 740 (Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Imm->getValue())); |
| 755 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { | 741 } else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { |
| 756 AssemblerFixup *Fixup = | 742 AssemblerFixup *Fixup = |
| 757 Asm->createFixup(InstX86Base<Machine>::Traits::RelFixup, Reloc); | 743 Asm->createFixup(InstX86Base<Machine>::Traits::RelFixup, Reloc); |
| 758 (Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Reloc->getOffset(), Fixup)); | 744 (Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Reloc->getOffset(), Fixup)); |
| 759 } else { | 745 } else { |
| 760 llvm_unreachable("Unexpected operand type"); | 746 llvm_unreachable("Unexpected operand type"); |
| 761 } | 747 } |
| 762 } | 748 } |
| 763 | 749 |
| 764 template <class Machine> | 750 template <class Machine> |
| 765 void emitIASAsAddrOpTyGPR( | 751 void emitIASAsAddrOpTyGPR( |
| 766 const Cfg *Func, Type Ty, const Operand *Op0, const Operand *Op1, | 752 const Cfg *Func, Type Ty, const Operand *Op0, const Operand *Op1, |
| 767 const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp | 753 const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp |
| 768 &Emitter) { | 754 &Emitter) { |
| 769 if (const auto Op0Var = llvm::dyn_cast<Variable>(Op0)) { | 755 if (const auto *Op0Var = llvm::dyn_cast<Variable>(Op0)) { |
| 770 assert(!Op0Var->hasReg()); | 756 assert(!Op0Var->hasReg()); |
| 771 typename InstX86Base<Machine>::Traits::Address StackAddr( | 757 typename InstX86Base<Machine>::Traits::Address StackAddr( |
| 772 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 758 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 773 Func->getTarget()) | 759 Func->getTarget()) |
| 774 ->stackVarToAsmOperand(Op0Var)); | 760 ->stackVarToAsmOperand(Op0Var)); |
| 775 emitIASAddrOpTyGPR<Machine>(Func, Ty, StackAddr, Op1, Emitter); | 761 emitIASAddrOpTyGPR<Machine>(Func, Ty, StackAddr, Op1, Emitter); |
| 776 } else if (const auto Op0Mem = llvm::dyn_cast< | 762 } else if (const auto *Op0Mem = llvm::dyn_cast< |
| 777 typename InstX86Base<Machine>::Traits::X86OperandMem>(Op0)) { | 763 typename InstX86Base<Machine>::Traits::X86OperandMem>(Op0)) { |
| 778 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 764 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 779 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 765 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 780 Op0Mem->emitSegmentOverride(Asm); | 766 Op0Mem->emitSegmentOverride(Asm); |
| 781 emitIASAddrOpTyGPR<Machine>(Func, Ty, Op0Mem->toAsmAddress(Asm), Op1, | 767 emitIASAddrOpTyGPR<Machine>(Func, Ty, Op0Mem->toAsmAddress(Asm), Op1, |
| 782 Emitter); | 768 Emitter); |
| 783 } else if (const auto Split = llvm::dyn_cast< | 769 } else if (const auto *Split = llvm::dyn_cast< |
| 784 typename InstX86Base<Machine>::Traits::VariableSplit>(Op0)) { | 770 typename InstX86Base<Machine>::Traits::VariableSplit>(Op0)) { |
| 785 emitIASAddrOpTyGPR<Machine>(Func, Ty, Split->toAsmAddress(Func), Op1, | 771 emitIASAddrOpTyGPR<Machine>(Func, Ty, Split->toAsmAddress(Func), Op1, |
| 786 Emitter); | 772 Emitter); |
| 787 } else { | 773 } else { |
| 788 llvm_unreachable("Unexpected operand type"); | 774 llvm_unreachable("Unexpected operand type"); |
| 789 } | 775 } |
| 790 } | 776 } |
| 791 | 777 |
| 792 template <class Machine> | 778 template <class Machine> |
| 793 void InstX86Base<Machine>::emitIASGPRShift( | 779 void InstX86Base<Machine>::emitIASGPRShift( |
| 794 const Cfg *Func, Type Ty, const Variable *Var, const Operand *Src, | 780 const Cfg *Func, Type Ty, const Variable *Var, const Operand *Src, |
| 795 const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterShiftOp | 781 const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterShiftOp |
| 796 &Emitter) { | 782 &Emitter) { |
| 797 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 783 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 798 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 784 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 799 // Technically, the Dest Var can be mem as well, but we only use Reg. We can | 785 // Technically, the Dest Var can be mem as well, but we only use Reg. We can |
| 800 // extend this to check Dest if we decide to use that form. | 786 // extend this to check Dest if we decide to use that form. |
| 801 assert(Var->hasReg()); | 787 assert(Var->hasReg()); |
| 802 // We cheat a little and use GPRRegister even for byte operations. | 788 // We cheat a little and use GPRRegister even for byte operations. |
| 803 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister VarReg = | 789 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister VarReg = |
| 804 InstX86Base<Machine>::Traits::RegisterSet::getEncodedByteRegOrGPR( | 790 InstX86Base<Machine>::Traits::getEncodedGPR(Var->getRegNum()); |
| 805 Ty, Var->getRegNum()); | |
| 806 // Src must be reg == ECX or an Imm8. This is asserted by the assembler. | 791 // Src must be reg == ECX or an Imm8. This is asserted by the assembler. |
| 807 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | 792 if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 808 assert(SrcVar->hasReg()); | 793 assert(SrcVar->hasReg()); |
| 809 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg = | 794 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg = |
| 810 InstX86Base<Machine>::Traits::RegisterSet::getEncodedByteRegOrGPR( | 795 InstX86Base<Machine>::Traits::getEncodedGPR(SrcVar->getRegNum()); |
| 811 Ty, SrcVar->getRegNum()); | |
| 812 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg); | 796 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg); |
| 813 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { | 797 } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
| 814 (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Imm->getValue())); | 798 (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Imm->getValue())); |
| 815 } else { | 799 } else { |
| 816 llvm_unreachable("Unexpected operand type"); | 800 llvm_unreachable("Unexpected operand type"); |
| 817 } | 801 } |
| 818 } | 802 } |
| 819 | 803 |
| 820 template <class Machine> | 804 template <class Machine> |
| 821 void emitIASGPRShiftDouble( | 805 void emitIASGPRShiftDouble( |
| 822 const Cfg *Func, const Variable *Dest, const Operand *Src1Op, | 806 const Cfg *Func, const Variable *Dest, const Operand *Src1Op, |
| 823 const Operand *Src2Op, | 807 const Operand *Src2Op, |
| 824 const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterShiftD | 808 const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterShiftD |
| 825 &Emitter) { | 809 &Emitter) { |
| 826 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 810 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 827 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 811 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 828 // Dest can be reg or mem, but we only use the reg variant. | 812 // Dest can be reg or mem, but we only use the reg variant. |
| 829 assert(Dest->hasReg()); | 813 assert(Dest->hasReg()); |
| 830 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister DestReg = | 814 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister DestReg = |
| 831 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | 815 InstX86Base<Machine>::Traits::getEncodedGPR(Dest->getRegNum()); |
| 832 Dest->getRegNum()); | |
| 833 // SrcVar1 must be reg. | 816 // SrcVar1 must be reg. |
| 834 const auto SrcVar1 = llvm::cast<Variable>(Src1Op); | 817 const auto *SrcVar1 = llvm::cast<Variable>(Src1Op); |
| 835 assert(SrcVar1->hasReg()); | 818 assert(SrcVar1->hasReg()); |
| 836 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg = | 819 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg = |
| 837 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | 820 InstX86Base<Machine>::Traits::getEncodedGPR(SrcVar1->getRegNum()); |
| 838 SrcVar1->getRegNum()); | |
| 839 Type Ty = SrcVar1->getType(); | 821 Type Ty = SrcVar1->getType(); |
| 840 // Src2 can be the implicit CL register or an immediate. | 822 // Src2 can be the implicit CL register or an immediate. |
| 841 if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src2Op)) { | 823 if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src2Op)) { |
| 842 (Asm->*(Emitter.GPRGPRImm))(Ty, DestReg, SrcReg, | 824 (Asm->*(Emitter.GPRGPRImm))(Ty, DestReg, SrcReg, |
| 843 Immediate(Imm->getValue())); | 825 Immediate(Imm->getValue())); |
| 844 } else { | 826 } else { |
| 845 assert(llvm::cast<Variable>(Src2Op)->getRegNum() == | 827 assert(llvm::cast<Variable>(Src2Op)->getRegNum() == |
| 846 InstX86Base<Machine>::Traits::RegisterSet::Reg_ecx); | 828 InstX86Base<Machine>::Traits::RegisterSet::Reg_cl); |
| 847 (Asm->*(Emitter.GPRGPR))(Ty, DestReg, SrcReg); | 829 (Asm->*(Emitter.GPRGPR))(Ty, DestReg, SrcReg); |
| 848 } | 830 } |
| 849 } | 831 } |
| 850 | 832 |
| 851 template <class Machine> | 833 template <class Machine> |
| 852 void emitIASXmmShift( | 834 void emitIASXmmShift( |
| 853 const Cfg *Func, Type Ty, const Variable *Var, const Operand *Src, | 835 const Cfg *Func, Type Ty, const Variable *Var, const Operand *Src, |
| 854 const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterShiftOp | 836 const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterShiftOp |
| 855 &Emitter) { | 837 &Emitter) { |
| 856 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 838 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 857 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 839 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 858 assert(Var->hasReg()); | 840 assert(Var->hasReg()); |
| 859 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister VarReg = | 841 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister VarReg = |
| 860 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( | 842 InstX86Base<Machine>::Traits::getEncodedXmm(Var->getRegNum()); |
| 861 Var->getRegNum()); | 843 if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 862 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | |
| 863 if (SrcVar->hasReg()) { | 844 if (SrcVar->hasReg()) { |
| 864 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg = | 845 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg = |
| 865 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( | 846 InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum()); |
| 866 SrcVar->getRegNum()); | |
| 867 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); | 847 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); |
| 868 } else { | 848 } else { |
| 869 typename InstX86Base<Machine>::Traits::Address SrcStackAddr = | 849 typename InstX86Base<Machine>::Traits::Address SrcStackAddr = |
| 870 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 850 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 871 Func->getTarget()) | 851 Func->getTarget()) |
| 872 ->stackVarToAsmOperand(SrcVar); | 852 ->stackVarToAsmOperand(SrcVar); |
| 873 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); | 853 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); |
| 874 } | 854 } |
| 875 } else if (const auto Mem = llvm::dyn_cast< | 855 } else if (const auto *Mem = llvm::dyn_cast< |
| 876 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) { | 856 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) { |
| 877 assert(Mem->getSegmentRegister() == | 857 assert(Mem->getSegmentRegister() == |
| 878 InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment); | 858 InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment); |
| 879 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); | 859 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); |
| 880 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { | 860 } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
| 881 (Asm->*(Emitter.XmmImm))(Ty, VarReg, Immediate(Imm->getValue())); | 861 (Asm->*(Emitter.XmmImm))(Ty, VarReg, Immediate(Imm->getValue())); |
| 882 } else { | 862 } else { |
| 883 llvm_unreachable("Unexpected operand type"); | 863 llvm_unreachable("Unexpected operand type"); |
| 884 } | 864 } |
| 885 } | 865 } |
| 886 | 866 |
| 887 template <class Machine> | 867 template <class Machine> |
| 888 void emitIASRegOpTyXMM( | 868 void emitIASRegOpTyXMM( |
| 889 const Cfg *Func, Type Ty, const Variable *Var, const Operand *Src, | 869 const Cfg *Func, Type Ty, const Variable *Var, const Operand *Src, |
| 890 const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp | 870 const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp |
| 891 &Emitter) { | 871 &Emitter) { |
| 892 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 872 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 893 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 873 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 894 assert(Var->hasReg()); | 874 assert(Var->hasReg()); |
| 895 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister VarReg = | 875 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister VarReg = |
| 896 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( | 876 InstX86Base<Machine>::Traits::getEncodedXmm(Var->getRegNum()); |
| 897 Var->getRegNum()); | 877 if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 898 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | |
| 899 if (SrcVar->hasReg()) { | 878 if (SrcVar->hasReg()) { |
| 900 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg = | 879 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg = |
| 901 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( | 880 InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum()); |
| 902 SrcVar->getRegNum()); | |
| 903 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); | 881 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); |
| 904 } else { | 882 } else { |
| 905 typename InstX86Base<Machine>::Traits::Address SrcStackAddr = | 883 typename InstX86Base<Machine>::Traits::Address SrcStackAddr = |
| 906 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 884 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 907 Func->getTarget()) | 885 Func->getTarget()) |
| 908 ->stackVarToAsmOperand(SrcVar); | 886 ->stackVarToAsmOperand(SrcVar); |
| 909 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); | 887 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); |
| 910 } | 888 } |
| 911 } else if (const auto Mem = llvm::dyn_cast< | 889 } else if (const auto *Mem = llvm::dyn_cast< |
| 912 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) { | 890 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) { |
| 913 assert(Mem->getSegmentRegister() == | 891 assert(Mem->getSegmentRegister() == |
| 914 InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment); | 892 InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment); |
| 915 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); | 893 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); |
| 916 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { | 894 } else if (const auto *Imm = llvm::dyn_cast<Constant>(Src)) { |
| 917 (Asm->*(Emitter.XmmAddr))( | 895 (Asm->*(Emitter.XmmAddr))( |
| 918 Ty, VarReg, | 896 Ty, VarReg, |
| 919 InstX86Base<Machine>::Traits::Address::ofConstPool(Asm, Imm)); | 897 InstX86Base<Machine>::Traits::Address::ofConstPool(Asm, Imm)); |
| 920 } else { | 898 } else { |
| 921 llvm_unreachable("Unexpected operand type"); | 899 llvm_unreachable("Unexpected operand type"); |
| 922 } | 900 } |
| 923 } | 901 } |
| 924 | 902 |
| 925 template <class Machine, typename DReg_t, typename SReg_t, | 903 template <class Machine, typename DReg_t, typename SReg_t, |
| 926 DReg_t (*destEnc)(int32_t), SReg_t (*srcEnc)(int32_t)> | 904 DReg_t (*destEnc)(int32_t), SReg_t (*srcEnc)(int32_t)> |
| 927 void emitIASCastRegOp(const Cfg *Func, Type DestTy, const Variable *Dest, | 905 void emitIASCastRegOp(const Cfg *Func, Type DestTy, const Variable *Dest, |
| 928 Type SrcTy, const Operand *Src, | 906 Type SrcTy, const Operand *Src, |
| 929 const typename InstX86Base<Machine>::Traits::Assembler:: | 907 const typename InstX86Base<Machine>::Traits::Assembler:: |
| 930 template CastEmitterRegOp<DReg_t, SReg_t> &Emitter) { | 908 template CastEmitterRegOp<DReg_t, SReg_t> &Emitter) { |
| 931 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 909 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 932 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 910 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 933 assert(Dest->hasReg()); | 911 assert(Dest->hasReg()); |
| 934 DReg_t DestReg = destEnc(Dest->getRegNum()); | 912 DReg_t DestReg = destEnc(Dest->getRegNum()); |
| 935 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | 913 if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 936 if (SrcVar->hasReg()) { | 914 if (SrcVar->hasReg()) { |
| 937 SReg_t SrcReg = srcEnc(SrcVar->getRegNum()); | 915 SReg_t SrcReg = srcEnc(SrcVar->getRegNum()); |
| 938 (Asm->*(Emitter.RegReg))(DestTy, DestReg, SrcTy, SrcReg); | 916 (Asm->*(Emitter.RegReg))(DestTy, DestReg, SrcTy, SrcReg); |
| 939 } else { | 917 } else { |
| 940 typename InstX86Base<Machine>::Traits::Address SrcStackAddr = | 918 typename InstX86Base<Machine>::Traits::Address SrcStackAddr = |
| 941 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 919 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 942 Func->getTarget()) | 920 Func->getTarget()) |
| 943 ->stackVarToAsmOperand(SrcVar); | 921 ->stackVarToAsmOperand(SrcVar); |
| 944 (Asm->*(Emitter.RegAddr))(DestTy, DestReg, SrcTy, SrcStackAddr); | 922 (Asm->*(Emitter.RegAddr))(DestTy, DestReg, SrcTy, SrcStackAddr); |
| 945 } | 923 } |
| 946 } else if (const auto Mem = llvm::dyn_cast< | 924 } else if (const auto *Mem = llvm::dyn_cast< |
| 947 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) { | 925 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) { |
| 948 Mem->emitSegmentOverride(Asm); | 926 Mem->emitSegmentOverride(Asm); |
| 949 (Asm->*(Emitter.RegAddr))(DestTy, DestReg, SrcTy, Mem->toAsmAddress(Asm)); | 927 (Asm->*(Emitter.RegAddr))(DestTy, DestReg, SrcTy, Mem->toAsmAddress(Asm)); |
| 950 } else { | 928 } else { |
| 951 llvm_unreachable("Unexpected operand type"); | 929 llvm_unreachable("Unexpected operand type"); |
| 952 } | 930 } |
| 953 } | 931 } |
| 954 | 932 |
| 955 template <class Machine, typename DReg_t, typename SReg_t, | 933 template <class Machine, typename DReg_t, typename SReg_t, |
| 956 DReg_t (*destEnc)(int32_t), SReg_t (*srcEnc)(int32_t)> | 934 DReg_t (*destEnc)(int32_t), SReg_t (*srcEnc)(int32_t)> |
| 957 void emitIASThreeOpImmOps( | 935 void emitIASThreeOpImmOps( |
| 958 const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src0, | 936 const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src0, |
| 959 const Operand *Src1, | 937 const Operand *Src1, |
| 960 const typename InstX86Base<Machine>::Traits::Assembler:: | 938 const typename InstX86Base<Machine>::Traits::Assembler:: |
| 961 template ThreeOpImmEmitter<DReg_t, SReg_t> Emitter) { | 939 template ThreeOpImmEmitter<DReg_t, SReg_t> Emitter) { |
| 962 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 940 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 963 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 941 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 964 // This only handles Dest being a register, and Src1 being an immediate. | 942 // This only handles Dest being a register, and Src1 being an immediate. |
| 965 assert(Dest->hasReg()); | 943 assert(Dest->hasReg()); |
| 966 DReg_t DestReg = destEnc(Dest->getRegNum()); | 944 DReg_t DestReg = destEnc(Dest->getRegNum()); |
| 967 Immediate Imm(llvm::cast<ConstantInteger32>(Src1)->getValue()); | 945 Immediate Imm(llvm::cast<ConstantInteger32>(Src1)->getValue()); |
| 968 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src0)) { | 946 if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src0)) { |
| 969 if (SrcVar->hasReg()) { | 947 if (SrcVar->hasReg()) { |
| 970 SReg_t SrcReg = srcEnc(SrcVar->getRegNum()); | 948 SReg_t SrcReg = srcEnc(SrcVar->getRegNum()); |
| 971 (Asm->*(Emitter.RegRegImm))(DispatchTy, DestReg, SrcReg, Imm); | 949 (Asm->*(Emitter.RegRegImm))(DispatchTy, DestReg, SrcReg, Imm); |
| 972 } else { | 950 } else { |
| 973 typename InstX86Base<Machine>::Traits::Address SrcStackAddr = | 951 typename InstX86Base<Machine>::Traits::Address SrcStackAddr = |
| 974 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 952 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 975 Func->getTarget()) | 953 Func->getTarget()) |
| 976 ->stackVarToAsmOperand(SrcVar); | 954 ->stackVarToAsmOperand(SrcVar); |
| 977 (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, SrcStackAddr, Imm); | 955 (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, SrcStackAddr, Imm); |
| 978 } | 956 } |
| 979 } else if (const auto Mem = llvm::dyn_cast< | 957 } else if (const auto *Mem = llvm::dyn_cast< |
| 980 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src0)) { | 958 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src0)) { |
| 981 Mem->emitSegmentOverride(Asm); | 959 Mem->emitSegmentOverride(Asm); |
| 982 (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, Mem->toAsmAddress(Asm), | 960 (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, Mem->toAsmAddress(Asm), |
| 983 Imm); | 961 Imm); |
| 984 } else { | 962 } else { |
| 985 llvm_unreachable("Unexpected operand type"); | 963 llvm_unreachable("Unexpected operand type"); |
| 986 } | 964 } |
| 987 } | 965 } |
| 988 | 966 |
| 989 template <class Machine> | 967 template <class Machine> |
| 990 void emitIASMovlikeXMM( | 968 void emitIASMovlikeXMM( |
| 991 const Cfg *Func, const Variable *Dest, const Operand *Src, | 969 const Cfg *Func, const Variable *Dest, const Operand *Src, |
| 992 const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterMovOps | 970 const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterMovOps |
| 993 Emitter) { | 971 Emitter) { |
| 994 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 972 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 995 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 973 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 996 if (Dest->hasReg()) { | 974 if (Dest->hasReg()) { |
| 997 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister DestReg = | 975 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister DestReg = |
| 998 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( | 976 InstX86Base<Machine>::Traits::getEncodedXmm(Dest->getRegNum()); |
| 999 Dest->getRegNum()); | 977 if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 1000 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | |
| 1001 if (SrcVar->hasReg()) { | 978 if (SrcVar->hasReg()) { |
| 1002 (Asm->*(Emitter.XmmXmm))( | 979 (Asm->*(Emitter.XmmXmm))( |
| 1003 DestReg, InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( | 980 DestReg, |
| 1004 SrcVar->getRegNum())); | 981 InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum())); |
| 1005 } else { | 982 } else { |
| 1006 typename InstX86Base<Machine>::Traits::Address StackAddr( | 983 typename InstX86Base<Machine>::Traits::Address StackAddr( |
| 1007 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering | 984 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering |
| 1008 *>(Func->getTarget()) | 985 *>(Func->getTarget()) |
| 1009 ->stackVarToAsmOperand(SrcVar)); | 986 ->stackVarToAsmOperand(SrcVar)); |
| 1010 (Asm->*(Emitter.XmmAddr))(DestReg, StackAddr); | 987 (Asm->*(Emitter.XmmAddr))(DestReg, StackAddr); |
| 1011 } | 988 } |
| 1012 } else if (const auto SrcMem = llvm::dyn_cast< | 989 } else if (const auto *SrcMem = llvm::dyn_cast< |
| 1013 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) { | 990 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) { |
| 1014 assert(SrcMem->getSegmentRegister() == | 991 assert(SrcMem->getSegmentRegister() == |
| 1015 InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment); | 992 InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment); |
| 1016 (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm)); | 993 (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm)); |
| 1017 } else { | 994 } else { |
| 1018 llvm_unreachable("Unexpected operand type"); | 995 llvm_unreachable("Unexpected operand type"); |
| 1019 } | 996 } |
| 1020 } else { | 997 } else { |
| 1021 typename InstX86Base<Machine>::Traits::Address StackAddr( | 998 typename InstX86Base<Machine>::Traits::Address StackAddr( |
| 1022 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 999 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 1023 Func->getTarget()) | 1000 Func->getTarget()) |
| 1024 ->stackVarToAsmOperand(Dest)); | 1001 ->stackVarToAsmOperand(Dest)); |
| 1025 // Src must be a register in this case. | 1002 // Src must be a register in this case. |
| 1026 const auto SrcVar = llvm::cast<Variable>(Src); | 1003 const auto *SrcVar = llvm::cast<Variable>(Src); |
| 1027 assert(SrcVar->hasReg()); | 1004 assert(SrcVar->hasReg()); |
| 1028 (Asm->*(Emitter.AddrXmm))( | 1005 (Asm->*(Emitter.AddrXmm))( |
| 1029 StackAddr, InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( | 1006 StackAddr, |
| 1030 SrcVar->getRegNum())); | 1007 InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum())); |
| 1031 } | 1008 } |
| 1032 } | 1009 } |
| 1033 | 1010 |
| 1034 template <class Machine> | 1011 template <class Machine> |
| 1035 void InstX86Sqrtss<Machine>::emit(const Cfg *Func) const { | 1012 void InstX86Sqrtss<Machine>::emit(const Cfg *Func) const { |
| 1036 if (!BuildDefs::dump()) | 1013 if (!BuildDefs::dump()) |
| 1037 return; | 1014 return; |
| 1038 Ostream &Str = Func->getContext()->getStrEmit(); | 1015 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1039 assert(this->getSrcSize() == 1); | 1016 assert(this->getSrcSize() == 1); |
| 1040 Type Ty = this->getSrc(0)->getType(); | 1017 Type Ty = this->getSrc(0)->getType(); |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1285 | 1262 |
| 1286 template <class Machine> | 1263 template <class Machine> |
| 1287 void InstX86Imul<Machine>::emit(const Cfg *Func) const { | 1264 void InstX86Imul<Machine>::emit(const Cfg *Func) const { |
| 1288 if (!BuildDefs::dump()) | 1265 if (!BuildDefs::dump()) |
| 1289 return; | 1266 return; |
| 1290 Ostream &Str = Func->getContext()->getStrEmit(); | 1267 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1291 assert(this->getSrcSize() == 2); | 1268 assert(this->getSrcSize() == 2); |
| 1292 Variable *Dest = this->getDest(); | 1269 Variable *Dest = this->getDest(); |
| 1293 if (isByteSizedArithType(Dest->getType())) { | 1270 if (isByteSizedArithType(Dest->getType())) { |
| 1294 // The 8-bit version of imul only allows the form "imul r/m8". | 1271 // The 8-bit version of imul only allows the form "imul r/m8". |
| 1295 const auto Src0Var = llvm::dyn_cast<Variable>(this->getSrc(0)); | 1272 const auto *Src0Var = llvm::dyn_cast<Variable>(this->getSrc(0)); |
| 1296 (void)Src0Var; | 1273 (void)Src0Var; |
| 1297 assert(Src0Var && | 1274 assert(Src0Var->getRegNum() == |
| 1298 Src0Var->getRegNum() == | 1275 InstX86Base<Machine>::Traits::RegisterSet::Reg_al); |
| 1299 InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); | |
| 1300 Str << "\timulb\t"; | 1276 Str << "\timulb\t"; |
| 1301 this->getSrc(1)->emit(Func); | 1277 this->getSrc(1)->emit(Func); |
| 1302 } else if (llvm::isa<Constant>(this->getSrc(1))) { | 1278 } else if (llvm::isa<Constant>(this->getSrc(1))) { |
| 1303 Str << "\timul" << this->getWidthString(Dest->getType()) << "\t"; | 1279 Str << "\timul" << this->getWidthString(Dest->getType()) << "\t"; |
| 1304 this->getSrc(1)->emit(Func); | 1280 this->getSrc(1)->emit(Func); |
| 1305 Str << ", "; | 1281 Str << ", "; |
| 1306 this->getSrc(0)->emit(Func); | 1282 this->getSrc(0)->emit(Func); |
| 1307 Str << ", "; | 1283 Str << ", "; |
| 1308 Dest->emit(Func); | 1284 Dest->emit(Func); |
| 1309 } else { | 1285 } else { |
| 1310 this->emitTwoAddress("imul", this, Func); | 1286 this->emitTwoAddress("imul", this, Func); |
| 1311 } | 1287 } |
| 1312 } | 1288 } |
| 1313 | 1289 |
| 1314 template <class Machine> | 1290 template <class Machine> |
| 1315 void InstX86Imul<Machine>::emitIAS(const Cfg *Func) const { | 1291 void InstX86Imul<Machine>::emitIAS(const Cfg *Func) const { |
| 1316 assert(this->getSrcSize() == 2); | 1292 assert(this->getSrcSize() == 2); |
| 1317 const Variable *Var = this->getDest(); | 1293 const Variable *Var = this->getDest(); |
| 1318 Type Ty = Var->getType(); | 1294 Type Ty = Var->getType(); |
| 1319 const Operand *Src = this->getSrc(1); | 1295 const Operand *Src = this->getSrc(1); |
| 1320 if (isByteSizedArithType(Ty)) { | 1296 if (isByteSizedArithType(Ty)) { |
| 1321 // The 8-bit version of imul only allows the form "imul r/m8". | 1297 // The 8-bit version of imul only allows the form "imul r/m8". |
| 1322 const auto Src0Var = llvm::dyn_cast<Variable>(this->getSrc(0)); | 1298 const auto *Src0Var = llvm::dyn_cast<Variable>(this->getSrc(0)); |
| 1323 (void)Src0Var; | 1299 (void)Src0Var; |
| 1324 assert(Src0Var && | 1300 assert(Src0Var->getRegNum() == |
| 1325 Src0Var->getRegNum() == | 1301 InstX86Base<Machine>::Traits::RegisterSet::Reg_al); |
| 1326 InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); | |
| 1327 static const typename InstX86Base< | 1302 static const typename InstX86Base< |
| 1328 Machine>::Traits::Assembler::GPREmitterOneOp Emitter = { | 1303 Machine>::Traits::Assembler::GPREmitterOneOp Emitter = { |
| 1329 &InstX86Base<Machine>::Traits::Assembler::imul, | 1304 &InstX86Base<Machine>::Traits::Assembler::imul, |
| 1330 &InstX86Base<Machine>::Traits::Assembler::imul}; | 1305 &InstX86Base<Machine>::Traits::Assembler::imul}; |
| 1331 emitIASOpTyGPR<Machine>(Func, Ty, this->getSrc(1), Emitter); | 1306 emitIASOpTyGPR<Machine>(Func, Ty, this->getSrc(1), Emitter); |
| 1332 } else { | 1307 } else { |
| 1333 // The two-address version is used when multiplying by a non-constant | 1308 // The two-address version is used when multiplying by a non-constant |
| 1334 // or doing an 8-bit multiply. | 1309 // or doing an 8-bit multiply. |
| 1335 assert(Var == this->getSrc(0)); | 1310 assert(Var == this->getSrc(0)); |
| 1336 static const typename InstX86Base< | 1311 static const typename InstX86Base< |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 1367 assert(llvm::isa<Constant>(this->getSrc(1))); | 1342 assert(llvm::isa<Constant>(this->getSrc(1))); |
| 1368 static const typename InstX86Base<Machine>::Traits::Assembler:: | 1343 static const typename InstX86Base<Machine>::Traits::Assembler:: |
| 1369 template ThreeOpImmEmitter< | 1344 template ThreeOpImmEmitter< |
| 1370 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, | 1345 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, |
| 1371 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister> | 1346 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister> |
| 1372 Emitter = {&InstX86Base<Machine>::Traits::Assembler::imul, | 1347 Emitter = {&InstX86Base<Machine>::Traits::Assembler::imul, |
| 1373 &InstX86Base<Machine>::Traits::Assembler::imul}; | 1348 &InstX86Base<Machine>::Traits::Assembler::imul}; |
| 1374 emitIASThreeOpImmOps< | 1349 emitIASThreeOpImmOps< |
| 1375 Machine, typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, | 1350 Machine, typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, |
| 1376 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, | 1351 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, |
| 1377 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR, | 1352 InstX86Base<Machine>::Traits::getEncodedGPR, |
| 1378 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR>( | 1353 InstX86Base<Machine>::Traits::getEncodedGPR>( |
| 1379 Func, Ty, Dest, this->getSrc(0), this->getSrc(1), Emitter); | 1354 Func, Ty, Dest, this->getSrc(0), this->getSrc(1), Emitter); |
| 1380 } | 1355 } |
| 1381 | 1356 |
| 1382 template <class Machine> | 1357 template <class Machine> |
| 1383 void InstX86Insertps<Machine>::emitIAS(const Cfg *Func) const { | 1358 void InstX86Insertps<Machine>::emitIAS(const Cfg *Func) const { |
| 1384 assert(this->getSrcSize() == 3); | 1359 assert(this->getSrcSize() == 3); |
| 1385 assert(static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 1360 assert(static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 1386 Func->getTarget()) | 1361 Func->getTarget()) |
| 1387 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1); | 1362 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1); |
| 1388 const Variable *Dest = this->getDest(); | 1363 const Variable *Dest = this->getDest(); |
| 1389 assert(Dest == this->getSrc(0)); | 1364 assert(Dest == this->getSrc(0)); |
| 1390 Type Ty = Dest->getType(); | 1365 Type Ty = Dest->getType(); |
| 1391 static const typename InstX86Base<Machine>::Traits::Assembler:: | 1366 static const typename InstX86Base<Machine>::Traits::Assembler:: |
| 1392 template ThreeOpImmEmitter< | 1367 template ThreeOpImmEmitter< |
| 1393 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, | 1368 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, |
| 1394 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister> | 1369 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister> |
| 1395 Emitter = {&InstX86Base<Machine>::Traits::Assembler::insertps, | 1370 Emitter = {&InstX86Base<Machine>::Traits::Assembler::insertps, |
| 1396 &InstX86Base<Machine>::Traits::Assembler::insertps}; | 1371 &InstX86Base<Machine>::Traits::Assembler::insertps}; |
| 1397 emitIASThreeOpImmOps< | 1372 emitIASThreeOpImmOps< |
| 1398 Machine, typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, | 1373 Machine, typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, |
| 1399 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, | 1374 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, |
| 1400 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm, | 1375 InstX86Base<Machine>::Traits::getEncodedXmm, |
| 1401 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm>( | 1376 InstX86Base<Machine>::Traits::getEncodedXmm>( |
| 1402 Func, Ty, Dest, this->getSrc(1), this->getSrc(2), Emitter); | 1377 Func, Ty, Dest, this->getSrc(1), this->getSrc(2), Emitter); |
| 1403 } | 1378 } |
| 1404 | 1379 |
| 1405 template <class Machine> | 1380 template <class Machine> |
| 1406 void InstX86Cbwdq<Machine>::emit(const Cfg *Func) const { | 1381 void InstX86Cbwdq<Machine>::emit(const Cfg *Func) const { |
| 1407 if (!BuildDefs::dump()) | 1382 if (!BuildDefs::dump()) |
| 1408 return; | 1383 return; |
| 1409 Ostream &Str = Func->getContext()->getStrEmit(); | 1384 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1410 assert(this->getSrcSize() == 1); | 1385 assert(this->getSrcSize() == 1); |
| 1411 Operand *Src0 = this->getSrc(0); | 1386 Operand *Src0 = this->getSrc(0); |
| 1412 assert(llvm::isa<Variable>(Src0)); | 1387 assert(llvm::isa<Variable>(Src0)); |
| 1413 assert(llvm::cast<Variable>(Src0)->getRegNum() == | |
| 1414 InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); | |
| 1415 switch (Src0->getType()) { | 1388 switch (Src0->getType()) { |
| 1416 default: | 1389 default: |
| 1417 llvm_unreachable("unexpected source type!"); | 1390 llvm_unreachable("unexpected source type!"); |
| 1418 break; | 1391 break; |
| 1419 case IceType_i8: | 1392 case IceType_i8: |
| 1393 assert(llvm::cast<Variable>(Src0)->getRegNum() == | |
| 1394 InstX86Base<Machine>::Traits::RegisterSet::Reg_al); | |
| 1420 assert(this->getDest()->getRegNum() == | 1395 assert(this->getDest()->getRegNum() == |
| 1421 InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); | 1396 InstX86Base<Machine>::Traits::RegisterSet::Reg_ax); |
| 1422 Str << "\t" | 1397 Str << "\t" |
| 1423 << "cbtw"; | 1398 << "cbtw"; |
| 1424 break; | 1399 break; |
| 1425 case IceType_i16: | 1400 case IceType_i16: |
| 1401 assert(llvm::cast<Variable>(Src0)->getRegNum() == | |
| 1402 InstX86Base<Machine>::Traits::RegisterSet::Reg_ax); | |
| 1426 assert(this->getDest()->getRegNum() == | 1403 assert(this->getDest()->getRegNum() == |
| 1427 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); | 1404 InstX86Base<Machine>::Traits::RegisterSet::Reg_dx); |
| 1428 Str << "\t" | 1405 Str << "\t" |
| 1429 << "cwtd"; | 1406 << "cwtd"; |
| 1430 break; | 1407 break; |
| 1431 case IceType_i32: | 1408 case IceType_i32: |
| 1409 assert(llvm::cast<Variable>(Src0)->getRegNum() == | |
| 1410 InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); | |
| 1432 assert(this->getDest()->getRegNum() == | 1411 assert(this->getDest()->getRegNum() == |
| 1433 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); | 1412 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
| 1434 Str << "\t" | 1413 Str << "\t" |
| 1435 << "cltd"; | 1414 << "cltd"; |
| 1436 break; | 1415 break; |
| 1437 case IceType_i64: | 1416 case IceType_i64: |
| 1438 assert(this->getDest()->getRegNum() == | 1417 assert(this->getDest()->getRegNum() == |
| 1439 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); | 1418 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
| 1440 Str << "\t" | 1419 Str << "\t" |
| 1441 << "cdto"; | 1420 << "cdto"; |
| 1442 break; | 1421 break; |
| 1443 } | 1422 } |
| 1444 } | 1423 } |
| 1445 | 1424 |
| 1446 template <class Machine> | 1425 template <class Machine> |
| 1447 void InstX86Cbwdq<Machine>::emitIAS(const Cfg *Func) const { | 1426 void InstX86Cbwdq<Machine>::emitIAS(const Cfg *Func) const { |
| 1448 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 1427 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 1449 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 1428 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 1450 assert(this->getSrcSize() == 1); | 1429 assert(this->getSrcSize() == 1); |
| 1451 Operand *Src0 = this->getSrc(0); | 1430 Operand *Src0 = this->getSrc(0); |
| 1452 assert(llvm::isa<Variable>(Src0)); | 1431 assert(llvm::isa<Variable>(Src0)); |
| 1453 assert(llvm::cast<Variable>(Src0)->getRegNum() == | |
| 1454 InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); | |
| 1455 switch (Src0->getType()) { | 1432 switch (Src0->getType()) { |
| 1456 default: | 1433 default: |
| 1457 llvm_unreachable("unexpected source type!"); | 1434 llvm_unreachable("unexpected source type!"); |
| 1458 break; | 1435 break; |
| 1459 case IceType_i8: | 1436 case IceType_i8: |
| 1437 assert(llvm::cast<Variable>(Src0)->getRegNum() == | |
| 1438 InstX86Base<Machine>::Traits::RegisterSet::Reg_al); | |
| 1460 assert(this->getDest()->getRegNum() == | 1439 assert(this->getDest()->getRegNum() == |
| 1461 InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); | 1440 InstX86Base<Machine>::Traits::RegisterSet::Reg_ax); |
| 1462 Asm->cbw(); | 1441 Asm->cbw(); |
| 1463 break; | 1442 break; |
| 1464 case IceType_i16: | 1443 case IceType_i16: |
| 1444 assert(llvm::cast<Variable>(Src0)->getRegNum() == | |
| 1445 InstX86Base<Machine>::Traits::RegisterSet::Reg_ax); | |
| 1465 assert(this->getDest()->getRegNum() == | 1446 assert(this->getDest()->getRegNum() == |
| 1466 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); | 1447 InstX86Base<Machine>::Traits::RegisterSet::Reg_dx); |
| 1467 Asm->cwd(); | 1448 Asm->cwd(); |
| 1468 break; | 1449 break; |
| 1469 case IceType_i32: | 1450 case IceType_i32: |
| 1451 assert(llvm::cast<Variable>(Src0)->getRegNum() == | |
| 1452 InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); | |
| 1470 assert(this->getDest()->getRegNum() == | 1453 assert(this->getDest()->getRegNum() == |
| 1471 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); | 1454 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
| 1472 Asm->cdq(); | 1455 Asm->cdq(); |
| 1473 break; | 1456 break; |
| 1474 case IceType_i64: | 1457 case IceType_i64: |
| 1475 assert(this->getDest()->getRegNum() == | 1458 assert(this->getDest()->getRegNum() == |
| 1476 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); | 1459 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
| 1477 Asm->cqo(); | 1460 Asm->cqo(); |
| 1478 break; | 1461 break; |
| 1479 } | 1462 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1522 | 1505 |
| 1523 template <class Machine> | 1506 template <class Machine> |
| 1524 void InstX86Shld<Machine>::emit(const Cfg *Func) const { | 1507 void InstX86Shld<Machine>::emit(const Cfg *Func) const { |
| 1525 if (!BuildDefs::dump()) | 1508 if (!BuildDefs::dump()) |
| 1526 return; | 1509 return; |
| 1527 Ostream &Str = Func->getContext()->getStrEmit(); | 1510 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1528 Variable *Dest = this->getDest(); | 1511 Variable *Dest = this->getDest(); |
| 1529 assert(this->getSrcSize() == 3); | 1512 assert(this->getSrcSize() == 3); |
| 1530 assert(Dest == this->getSrc(0)); | 1513 assert(Dest == this->getSrc(0)); |
| 1531 Str << "\tshld" << this->getWidthString(Dest->getType()) << "\t"; | 1514 Str << "\tshld" << this->getWidthString(Dest->getType()) << "\t"; |
| 1532 if (const auto ShiftReg = llvm::dyn_cast<Variable>(this->getSrc(2))) { | 1515 this->getSrc(2)->emit(Func); |
| 1533 (void)ShiftReg; | |
| 1534 assert(ShiftReg->getRegNum() == | |
| 1535 InstX86Base<Machine>::Traits::RegisterSet::Reg_ecx); | |
| 1536 Str << "%cl"; | |
| 1537 } else { | |
| 1538 this->getSrc(2)->emit(Func); | |
| 1539 } | |
| 1540 Str << ", "; | 1516 Str << ", "; |
| 1541 this->getSrc(1)->emit(Func); | 1517 this->getSrc(1)->emit(Func); |
| 1542 Str << ", "; | 1518 Str << ", "; |
| 1543 Dest->emit(Func); | 1519 Dest->emit(Func); |
| 1544 } | 1520 } |
| 1545 | 1521 |
| 1546 template <class Machine> | 1522 template <class Machine> |
| 1547 void InstX86Shld<Machine>::emitIAS(const Cfg *Func) const { | 1523 void InstX86Shld<Machine>::emitIAS(const Cfg *Func) const { |
| 1548 assert(this->getSrcSize() == 3); | 1524 assert(this->getSrcSize() == 3); |
| 1549 assert(this->getDest() == this->getSrc(0)); | 1525 assert(this->getDest() == this->getSrc(0)); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 1569 | 1545 |
| 1570 template <class Machine> | 1546 template <class Machine> |
| 1571 void InstX86Shrd<Machine>::emit(const Cfg *Func) const { | 1547 void InstX86Shrd<Machine>::emit(const Cfg *Func) const { |
| 1572 if (!BuildDefs::dump()) | 1548 if (!BuildDefs::dump()) |
| 1573 return; | 1549 return; |
| 1574 Ostream &Str = Func->getContext()->getStrEmit(); | 1550 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1575 Variable *Dest = this->getDest(); | 1551 Variable *Dest = this->getDest(); |
| 1576 assert(this->getSrcSize() == 3); | 1552 assert(this->getSrcSize() == 3); |
| 1577 assert(Dest == this->getSrc(0)); | 1553 assert(Dest == this->getSrc(0)); |
| 1578 Str << "\tshrd" << this->getWidthString(Dest->getType()) << "\t"; | 1554 Str << "\tshrd" << this->getWidthString(Dest->getType()) << "\t"; |
| 1579 if (const auto ShiftReg = llvm::dyn_cast<Variable>(this->getSrc(2))) { | 1555 this->getSrc(2)->emit(Func); |
| 1580 (void)ShiftReg; | |
| 1581 assert(ShiftReg->getRegNum() == | |
| 1582 InstX86Base<Machine>::Traits::RegisterSet::Reg_ecx); | |
| 1583 Str << "%cl"; | |
| 1584 } else { | |
| 1585 this->getSrc(2)->emit(Func); | |
| 1586 } | |
| 1587 Str << ", "; | 1556 Str << ", "; |
| 1588 this->getSrc(1)->emit(Func); | 1557 this->getSrc(1)->emit(Func); |
| 1589 Str << ", "; | 1558 Str << ", "; |
| 1590 Dest->emit(Func); | 1559 Dest->emit(Func); |
| 1591 } | 1560 } |
| 1592 | 1561 |
| 1593 template <class Machine> | 1562 template <class Machine> |
| 1594 void InstX86Shrd<Machine>::emitIAS(const Cfg *Func) const { | 1563 void InstX86Shrd<Machine>::emitIAS(const Cfg *Func) const { |
| 1595 assert(this->getSrcSize() == 3); | 1564 assert(this->getSrcSize() == 3); |
| 1596 assert(this->getDest() == this->getSrc(0)); | 1565 assert(this->getDest() == this->getSrc(0)); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1637 assert(this->getDest()->hasReg()); | 1606 assert(this->getDest()->hasReg()); |
| 1638 assert(this->getSrcSize() == 2); | 1607 assert(this->getSrcSize() == 2); |
| 1639 Operand *Src = this->getSrc(1); | 1608 Operand *Src = this->getSrc(1); |
| 1640 Type SrcTy = Src->getType(); | 1609 Type SrcTy = Src->getType(); |
| 1641 assert(SrcTy == IceType_i16 || SrcTy == IceType_i32 || | 1610 assert(SrcTy == IceType_i16 || SrcTy == IceType_i32 || |
| 1642 (InstX86Base<Machine>::Traits::Is64Bit)); | 1611 (InstX86Base<Machine>::Traits::Is64Bit)); |
| 1643 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 1612 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 1644 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 1613 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 1645 if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { | 1614 if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 1646 if (SrcVar->hasReg()) { | 1615 if (SrcVar->hasReg()) { |
| 1647 Asm->cmov(SrcTy, Condition, | 1616 Asm->cmov( |
| 1648 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | 1617 SrcTy, Condition, InstX86Base<Machine>::Traits::getEncodedGPR( |
| 1649 this->getDest()->getRegNum()), | 1618 this->getDest()->getRegNum()), |
| 1650 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | 1619 InstX86Base<Machine>::Traits::getEncodedGPR(SrcVar->getRegNum())); |
| 1651 SrcVar->getRegNum())); | |
| 1652 } else { | 1620 } else { |
| 1653 Asm->cmov( | 1621 Asm->cmov( |
| 1654 SrcTy, Condition, | 1622 SrcTy, Condition, InstX86Base<Machine>::Traits::getEncodedGPR( |
| 1655 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | 1623 this->getDest()->getRegNum()), |
| 1656 this->getDest()->getRegNum()), | |
| 1657 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 1624 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 1658 Func->getTarget()) | 1625 Func->getTarget()) |
| 1659 ->stackVarToAsmOperand(SrcVar)); | 1626 ->stackVarToAsmOperand(SrcVar)); |
| 1660 } | 1627 } |
| 1661 } else if (const auto Mem = llvm::dyn_cast< | 1628 } else if (const auto *Mem = llvm::dyn_cast< |
| 1662 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) { | 1629 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) { |
| 1663 assert(Mem->getSegmentRegister() == | 1630 assert(Mem->getSegmentRegister() == |
| 1664 InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment); | 1631 InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment); |
| 1665 Asm->cmov(SrcTy, Condition, | 1632 Asm->cmov(SrcTy, Condition, InstX86Base<Machine>::Traits::getEncodedGPR( |
| 1666 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | 1633 this->getDest()->getRegNum()), |
| 1667 this->getDest()->getRegNum()), | |
| 1668 Mem->toAsmAddress(Asm)); | 1634 Mem->toAsmAddress(Asm)); |
| 1669 } else { | 1635 } else { |
| 1670 llvm_unreachable("Unexpected operand type"); | 1636 llvm_unreachable("Unexpected operand type"); |
| 1671 } | 1637 } |
| 1672 } | 1638 } |
| 1673 | 1639 |
| 1674 template <class Machine> | 1640 template <class Machine> |
| 1675 void InstX86Cmov<Machine>::dump(const Cfg *Func) const { | 1641 void InstX86Cmov<Machine>::dump(const Cfg *Func) const { |
| 1676 if (!BuildDefs::dump()) | 1642 if (!BuildDefs::dump()) |
| 1677 return; | 1643 return; |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 1704 | 1670 |
| 1705 template <class Machine> | 1671 template <class Machine> |
| 1706 void InstX86Cmpps<Machine>::emitIAS(const Cfg *Func) const { | 1672 void InstX86Cmpps<Machine>::emitIAS(const Cfg *Func) const { |
| 1707 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 1673 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 1708 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 1674 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 1709 assert(this->getSrcSize() == 2); | 1675 assert(this->getSrcSize() == 2); |
| 1710 assert(Condition < InstX86Base<Machine>::Traits::Cond::Cmpps_Invalid); | 1676 assert(Condition < InstX86Base<Machine>::Traits::Cond::Cmpps_Invalid); |
| 1711 // Assuming there isn't any load folding for cmpps, and vector constants are | 1677 // Assuming there isn't any load folding for cmpps, and vector constants are |
| 1712 // not allowed in PNaCl. | 1678 // not allowed in PNaCl. |
| 1713 assert(llvm::isa<Variable>(this->getSrc(1))); | 1679 assert(llvm::isa<Variable>(this->getSrc(1))); |
| 1714 const auto SrcVar = llvm::cast<Variable>(this->getSrc(1)); | 1680 const auto *SrcVar = llvm::cast<Variable>(this->getSrc(1)); |
| 1715 if (SrcVar->hasReg()) { | 1681 if (SrcVar->hasReg()) { |
| 1716 Asm->cmpps(InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( | 1682 Asm->cmpps(InstX86Base<Machine>::Traits::getEncodedXmm( |
| 1717 this->getDest()->getRegNum()), | 1683 this->getDest()->getRegNum()), |
| 1718 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( | 1684 InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum()), |
| 1719 SrcVar->getRegNum()), | |
| 1720 Condition); | 1685 Condition); |
| 1721 } else { | 1686 } else { |
| 1722 typename InstX86Base<Machine>::Traits::Address SrcStackAddr = | 1687 typename InstX86Base<Machine>::Traits::Address SrcStackAddr = |
| 1723 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 1688 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 1724 Func->getTarget()) | 1689 Func->getTarget()) |
| 1725 ->stackVarToAsmOperand(SrcVar); | 1690 ->stackVarToAsmOperand(SrcVar); |
| 1726 Asm->cmpps(InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( | 1691 Asm->cmpps(InstX86Base<Machine>::Traits::getEncodedXmm( |
| 1727 this->getDest()->getRegNum()), | 1692 this->getDest()->getRegNum()), |
| 1728 SrcStackAddr, Condition); | 1693 SrcStackAddr, Condition); |
| 1729 } | 1694 } |
| 1730 } | 1695 } |
| 1731 | 1696 |
| 1732 template <class Machine> | 1697 template <class Machine> |
| 1733 void InstX86Cmpps<Machine>::dump(const Cfg *Func) const { | 1698 void InstX86Cmpps<Machine>::dump(const Cfg *Func) const { |
| 1734 if (!BuildDefs::dump()) | 1699 if (!BuildDefs::dump()) |
| 1735 return; | 1700 return; |
| 1736 Ostream &Str = Func->getContext()->getStrDump(); | 1701 Ostream &Str = Func->getContext()->getStrDump(); |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 1765 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 1730 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 1766 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 1731 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 1767 Type Ty = this->getSrc(0)->getType(); | 1732 Type Ty = this->getSrc(0)->getType(); |
| 1768 const auto Mem = | 1733 const auto Mem = |
| 1769 llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>( | 1734 llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>( |
| 1770 this->getSrc(0)); | 1735 this->getSrc(0)); |
| 1771 assert(Mem->getSegmentRegister() == | 1736 assert(Mem->getSegmentRegister() == |
| 1772 InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment); | 1737 InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment); |
| 1773 const typename InstX86Base<Machine>::Traits::Address Addr = | 1738 const typename InstX86Base<Machine>::Traits::Address Addr = |
| 1774 Mem->toAsmAddress(Asm); | 1739 Mem->toAsmAddress(Asm); |
| 1775 const auto VarReg = llvm::cast<Variable>(this->getSrc(2)); | 1740 const auto *VarReg = llvm::cast<Variable>(this->getSrc(2)); |
| 1776 assert(VarReg->hasReg()); | 1741 assert(VarReg->hasReg()); |
| 1777 const typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister Reg = | 1742 const typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister Reg = |
| 1778 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | 1743 InstX86Base<Machine>::Traits::getEncodedGPR(VarReg->getRegNum()); |
| 1779 VarReg->getRegNum()); | |
| 1780 Asm->cmpxchg(Ty, Addr, Reg, this->Locked); | 1744 Asm->cmpxchg(Ty, Addr, Reg, this->Locked); |
| 1781 } | 1745 } |
| 1782 | 1746 |
| 1783 template <class Machine> | 1747 template <class Machine> |
| 1784 void InstX86Cmpxchg<Machine>::dump(const Cfg *Func) const { | 1748 void InstX86Cmpxchg<Machine>::dump(const Cfg *Func) const { |
| 1785 if (!BuildDefs::dump()) | 1749 if (!BuildDefs::dump()) |
| 1786 return; | 1750 return; |
| 1787 Ostream &Str = Func->getContext()->getStrDump(); | 1751 Ostream &Str = Func->getContext()->getStrDump(); |
| 1788 if (this->Locked) { | 1752 if (this->Locked) { |
| 1789 Str << "lock "; | 1753 Str << "lock "; |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1870 static const typename InstX86Base<Machine>::Traits::Assembler:: | 1834 static const typename InstX86Base<Machine>::Traits::Assembler:: |
| 1871 template CastEmitterRegOp< | 1835 template CastEmitterRegOp< |
| 1872 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, | 1836 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, |
| 1873 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister> | 1837 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister> |
| 1874 Emitter = {&InstX86Base<Machine>::Traits::Assembler::cvtsi2ss, | 1838 Emitter = {&InstX86Base<Machine>::Traits::Assembler::cvtsi2ss, |
| 1875 &InstX86Base<Machine>::Traits::Assembler::cvtsi2ss}; | 1839 &InstX86Base<Machine>::Traits::Assembler::cvtsi2ss}; |
| 1876 emitIASCastRegOp< | 1840 emitIASCastRegOp< |
| 1877 Machine, | 1841 Machine, |
| 1878 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, | 1842 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, |
| 1879 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, | 1843 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, |
| 1880 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm, | 1844 InstX86Base<Machine>::Traits::getEncodedXmm, |
| 1881 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR>( | 1845 InstX86Base<Machine>::Traits::getEncodedGPR>(Func, DestTy, Dest, SrcTy, |
| 1882 Func, DestTy, Dest, SrcTy, Src, Emitter); | 1846 Src, Emitter); |
| 1883 return; | 1847 return; |
| 1884 } | 1848 } |
| 1885 case Tss2si: { | 1849 case Tss2si: { |
| 1886 assert(isScalarFloatingType(SrcTy)); | 1850 assert(isScalarFloatingType(SrcTy)); |
| 1887 assert(isScalarIntegerType(DestTy)); | 1851 assert(isScalarIntegerType(DestTy)); |
| 1888 if (!InstX86Base<Machine>::Traits::Is64Bit) { | 1852 if (!InstX86Base<Machine>::Traits::Is64Bit) { |
| 1889 assert(typeWidthInBytes(DestTy) <= 4); | 1853 assert(typeWidthInBytes(DestTy) <= 4); |
| 1890 } else { | 1854 } else { |
| 1891 assert(DestTy == IceType_i32 || DestTy == IceType_i64); | 1855 assert(DestTy == IceType_i32 || DestTy == IceType_i64); |
| 1892 } | 1856 } |
| 1893 static const typename InstX86Base<Machine>::Traits::Assembler:: | 1857 static const typename InstX86Base<Machine>::Traits::Assembler:: |
| 1894 template CastEmitterRegOp< | 1858 template CastEmitterRegOp< |
| 1895 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, | 1859 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, |
| 1896 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister> | 1860 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister> |
| 1897 Emitter = {&InstX86Base<Machine>::Traits::Assembler::cvttss2si, | 1861 Emitter = {&InstX86Base<Machine>::Traits::Assembler::cvttss2si, |
| 1898 &InstX86Base<Machine>::Traits::Assembler::cvttss2si}; | 1862 &InstX86Base<Machine>::Traits::Assembler::cvttss2si}; |
| 1899 emitIASCastRegOp< | 1863 emitIASCastRegOp< |
| 1900 Machine, | 1864 Machine, |
| 1901 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, | 1865 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, |
| 1902 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, | 1866 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, |
| 1903 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR, | 1867 InstX86Base<Machine>::Traits::getEncodedGPR, |
| 1904 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm>( | 1868 InstX86Base<Machine>::Traits::getEncodedXmm>(Func, DestTy, Dest, SrcTy, |
| 1905 Func, DestTy, Dest, SrcTy, Src, Emitter); | 1869 Src, Emitter); |
| 1906 return; | 1870 return; |
| 1907 } | 1871 } |
| 1908 case Float2float: { | 1872 case Float2float: { |
| 1909 assert(isScalarFloatingType(SrcTy)); | 1873 assert(isScalarFloatingType(SrcTy)); |
| 1910 assert(isScalarFloatingType(DestTy)); | 1874 assert(isScalarFloatingType(DestTy)); |
| 1911 assert(DestTy != SrcTy); | 1875 assert(DestTy != SrcTy); |
| 1912 static const typename InstX86Base< | 1876 static const typename InstX86Base< |
| 1913 Machine>::Traits::Assembler::XmmEmitterRegOp Emitter = { | 1877 Machine>::Traits::Assembler::XmmEmitterRegOp Emitter = { |
| 1914 &InstX86Base<Machine>::Traits::Assembler::cvtfloat2float, | 1878 &InstX86Base<Machine>::Traits::Assembler::cvtfloat2float, |
| 1915 &InstX86Base<Machine>::Traits::Assembler::cvtfloat2float}; | 1879 &InstX86Base<Machine>::Traits::Assembler::cvtfloat2float}; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1975 const Operand *Src1 = this->getSrc(1); | 1939 const Operand *Src1 = this->getSrc(1); |
| 1976 Type Ty = Src0->getType(); | 1940 Type Ty = Src0->getType(); |
| 1977 static const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp | 1941 static const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp |
| 1978 RegEmitter = {&InstX86Base<Machine>::Traits::Assembler::cmp, | 1942 RegEmitter = {&InstX86Base<Machine>::Traits::Assembler::cmp, |
| 1979 &InstX86Base<Machine>::Traits::Assembler::cmp, | 1943 &InstX86Base<Machine>::Traits::Assembler::cmp, |
| 1980 &InstX86Base<Machine>::Traits::Assembler::cmp}; | 1944 &InstX86Base<Machine>::Traits::Assembler::cmp}; |
| 1981 static const typename InstX86Base< | 1945 static const typename InstX86Base< |
| 1982 Machine>::Traits::Assembler::GPREmitterAddrOp AddrEmitter = { | 1946 Machine>::Traits::Assembler::GPREmitterAddrOp AddrEmitter = { |
| 1983 &InstX86Base<Machine>::Traits::Assembler::cmp, | 1947 &InstX86Base<Machine>::Traits::Assembler::cmp, |
| 1984 &InstX86Base<Machine>::Traits::Assembler::cmp}; | 1948 &InstX86Base<Machine>::Traits::Assembler::cmp}; |
| 1985 if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) { | 1949 if (const auto *SrcVar0 = llvm::dyn_cast<Variable>(Src0)) { |
| 1986 if (SrcVar0->hasReg()) { | 1950 if (SrcVar0->hasReg()) { |
| 1987 emitIASRegOpTyGPR<Machine>(Func, Ty, SrcVar0, Src1, RegEmitter); | 1951 emitIASRegOpTyGPR<Machine>(Func, Ty, SrcVar0, Src1, RegEmitter); |
| 1988 return; | 1952 return; |
| 1989 } | 1953 } |
| 1990 } | 1954 } |
| 1991 emitIASAsAddrOpTyGPR<Machine>(Func, Ty, Src0, Src1, AddrEmitter); | 1955 emitIASAsAddrOpTyGPR<Machine>(Func, Ty, Src0, Src1, AddrEmitter); |
| 1992 } | 1956 } |
| 1993 | 1957 |
| 1994 template <class Machine> | 1958 template <class Machine> |
| 1995 void InstX86Icmp<Machine>::dump(const Cfg *Func) const { | 1959 void InstX86Icmp<Machine>::dump(const Cfg *Func) const { |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 2014 Str << ", "; | 1978 Str << ", "; |
| 2015 this->getSrc(0)->emit(Func); | 1979 this->getSrc(0)->emit(Func); |
| 2016 } | 1980 } |
| 2017 | 1981 |
| 2018 template <class Machine> | 1982 template <class Machine> |
| 2019 void InstX86Ucomiss<Machine>::emitIAS(const Cfg *Func) const { | 1983 void InstX86Ucomiss<Machine>::emitIAS(const Cfg *Func) const { |
| 2020 assert(this->getSrcSize() == 2); | 1984 assert(this->getSrcSize() == 2); |
| 2021 // Currently src0 is always a variable by convention, to avoid having two | 1985 // Currently src0 is always a variable by convention, to avoid having two |
| 2022 // memory operands. | 1986 // memory operands. |
| 2023 assert(llvm::isa<Variable>(this->getSrc(0))); | 1987 assert(llvm::isa<Variable>(this->getSrc(0))); |
| 2024 const auto Src0Var = llvm::cast<Variable>(this->getSrc(0)); | 1988 const auto *Src0Var = llvm::cast<Variable>(this->getSrc(0)); |
| 2025 Type Ty = Src0Var->getType(); | 1989 Type Ty = Src0Var->getType(); |
| 2026 static const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp | 1990 static const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp |
| 2027 Emitter = {&InstX86Base<Machine>::Traits::Assembler::ucomiss, | 1991 Emitter = {&InstX86Base<Machine>::Traits::Assembler::ucomiss, |
| 2028 &InstX86Base<Machine>::Traits::Assembler::ucomiss}; | 1992 &InstX86Base<Machine>::Traits::Assembler::ucomiss}; |
| 2029 emitIASRegOpTyXMM<Machine>(Func, Ty, Src0Var, this->getSrc(1), Emitter); | 1993 emitIASRegOpTyXMM<Machine>(Func, Ty, Src0Var, this->getSrc(1), Emitter); |
| 2030 } | 1994 } |
| 2031 | 1995 |
| 2032 template <class Machine> | 1996 template <class Machine> |
| 2033 void InstX86Ucomiss<Machine>::dump(const Cfg *Func) const { | 1997 void InstX86Ucomiss<Machine>::dump(const Cfg *Func) const { |
| 2034 if (!BuildDefs::dump()) | 1998 if (!BuildDefs::dump()) |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2079 const Operand *Src1 = this->getSrc(1); | 2043 const Operand *Src1 = this->getSrc(1); |
| 2080 Type Ty = Src0->getType(); | 2044 Type Ty = Src0->getType(); |
| 2081 // The Reg/Addr form of test is not encodeable. | 2045 // The Reg/Addr form of test is not encodeable. |
| 2082 static const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp | 2046 static const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp |
| 2083 RegEmitter = {&InstX86Base<Machine>::Traits::Assembler::test, nullptr, | 2047 RegEmitter = {&InstX86Base<Machine>::Traits::Assembler::test, nullptr, |
| 2084 &InstX86Base<Machine>::Traits::Assembler::test}; | 2048 &InstX86Base<Machine>::Traits::Assembler::test}; |
| 2085 static const typename InstX86Base< | 2049 static const typename InstX86Base< |
| 2086 Machine>::Traits::Assembler::GPREmitterAddrOp AddrEmitter = { | 2050 Machine>::Traits::Assembler::GPREmitterAddrOp AddrEmitter = { |
| 2087 &InstX86Base<Machine>::Traits::Assembler::test, | 2051 &InstX86Base<Machine>::Traits::Assembler::test, |
| 2088 &InstX86Base<Machine>::Traits::Assembler::test}; | 2052 &InstX86Base<Machine>::Traits::Assembler::test}; |
| 2089 if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) { | 2053 if (const auto *SrcVar0 = llvm::dyn_cast<Variable>(Src0)) { |
| 2090 if (SrcVar0->hasReg()) { | 2054 if (SrcVar0->hasReg()) { |
| 2091 emitIASRegOpTyGPR<Machine>(Func, Ty, SrcVar0, Src1, RegEmitter); | 2055 emitIASRegOpTyGPR<Machine>(Func, Ty, SrcVar0, Src1, RegEmitter); |
| 2092 return; | 2056 return; |
| 2093 } | 2057 } |
| 2094 } | 2058 } |
| 2095 emitIASAsAddrOpTyGPR<Machine>(Func, Ty, Src0, Src1, AddrEmitter); | 2059 emitIASAsAddrOpTyGPR<Machine>(Func, Ty, Src0, Src1, AddrEmitter); |
| 2096 } | 2060 } |
| 2097 | 2061 |
| 2098 template <class Machine> | 2062 template <class Machine> |
| 2099 void InstX86Test<Machine>::dump(const Cfg *Func) const { | 2063 void InstX86Test<Machine>::dump(const Cfg *Func) const { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2143 } | 2107 } |
| 2144 | 2108 |
| 2145 template <class Machine> | 2109 template <class Machine> |
| 2146 void InstX86Store<Machine>::emitIAS(const Cfg *Func) const { | 2110 void InstX86Store<Machine>::emitIAS(const Cfg *Func) const { |
| 2147 assert(this->getSrcSize() == 2); | 2111 assert(this->getSrcSize() == 2); |
| 2148 const Operand *Dest = this->getSrc(1); | 2112 const Operand *Dest = this->getSrc(1); |
| 2149 const Operand *Src = this->getSrc(0); | 2113 const Operand *Src = this->getSrc(0); |
| 2150 Type DestTy = Dest->getType(); | 2114 Type DestTy = Dest->getType(); |
| 2151 if (isScalarFloatingType(DestTy)) { | 2115 if (isScalarFloatingType(DestTy)) { |
| 2152 // Src must be a register, since Dest is a Mem operand of some kind. | 2116 // Src must be a register, since Dest is a Mem operand of some kind. |
| 2153 const auto SrcVar = llvm::cast<Variable>(Src); | 2117 const auto *SrcVar = llvm::cast<Variable>(Src); |
| 2154 assert(SrcVar->hasReg()); | 2118 assert(SrcVar->hasReg()); |
| 2155 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg = | 2119 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg = |
| 2156 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( | 2120 InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum()); |
| 2157 SrcVar->getRegNum()); | |
| 2158 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 2121 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 2159 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 2122 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 2160 if (const auto DestVar = llvm::dyn_cast<Variable>(Dest)) { | 2123 if (const auto *DestVar = llvm::dyn_cast<Variable>(Dest)) { |
| 2161 assert(!DestVar->hasReg()); | 2124 assert(!DestVar->hasReg()); |
| 2162 typename InstX86Base<Machine>::Traits::Address StackAddr( | 2125 typename InstX86Base<Machine>::Traits::Address StackAddr( |
| 2163 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 2126 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 2164 Func->getTarget()) | 2127 Func->getTarget()) |
| 2165 ->stackVarToAsmOperand(DestVar)); | 2128 ->stackVarToAsmOperand(DestVar)); |
| 2166 Asm->movss(DestTy, StackAddr, SrcReg); | 2129 Asm->movss(DestTy, StackAddr, SrcReg); |
| 2167 } else { | 2130 } else { |
| 2168 const auto DestMem = | 2131 const auto DestMem = |
| 2169 llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>( | 2132 llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>( |
| 2170 Dest); | 2133 Dest); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2205 this->getSrc(0)->emit(Func); | 2168 this->getSrc(0)->emit(Func); |
| 2206 Str << ", "; | 2169 Str << ", "; |
| 2207 this->getSrc(1)->emit(Func); | 2170 this->getSrc(1)->emit(Func); |
| 2208 } | 2171 } |
| 2209 | 2172 |
| 2210 template <class Machine> | 2173 template <class Machine> |
| 2211 void InstX86StoreP<Machine>::emitIAS(const Cfg *Func) const { | 2174 void InstX86StoreP<Machine>::emitIAS(const Cfg *Func) const { |
| 2212 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 2175 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 2213 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 2176 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 2214 assert(this->getSrcSize() == 2); | 2177 assert(this->getSrcSize() == 2); |
| 2215 const auto SrcVar = llvm::cast<Variable>(this->getSrc(0)); | 2178 const auto *SrcVar = llvm::cast<Variable>(this->getSrc(0)); |
| 2216 const auto DestMem = | 2179 const auto DestMem = |
| 2217 llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>( | 2180 llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>( |
| 2218 this->getSrc(1)); | 2181 this->getSrc(1)); |
| 2219 assert(DestMem->getSegmentRegister() == | 2182 assert(DestMem->getSegmentRegister() == |
| 2220 InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment); | 2183 InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment); |
| 2221 assert(SrcVar->hasReg()); | 2184 assert(SrcVar->hasReg()); |
| 2222 Asm->movups(DestMem->toAsmAddress(Asm), | 2185 Asm->movups(DestMem->toAsmAddress(Asm), |
| 2223 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( | 2186 InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum())); |
| 2224 SrcVar->getRegNum())); | |
| 2225 } | 2187 } |
| 2226 | 2188 |
| 2227 template <class Machine> | 2189 template <class Machine> |
| 2228 void InstX86StoreP<Machine>::dump(const Cfg *Func) const { | 2190 void InstX86StoreP<Machine>::dump(const Cfg *Func) const { |
| 2229 if (!BuildDefs::dump()) | 2191 if (!BuildDefs::dump()) |
| 2230 return; | 2192 return; |
| 2231 Ostream &Str = Func->getContext()->getStrDump(); | 2193 Ostream &Str = Func->getContext()->getStrDump(); |
| 2232 Str << "storep." << this->getSrc(0)->getType() << " "; | 2194 Str << "storep." << this->getSrc(0)->getType() << " "; |
| 2233 this->getSrc(1)->dump(Func); | 2195 this->getSrc(1)->dump(Func); |
| 2234 Str << ", "; | 2196 Str << ", "; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 2248 this->getSrc(0)->emit(Func); | 2210 this->getSrc(0)->emit(Func); |
| 2249 Str << ", "; | 2211 Str << ", "; |
| 2250 this->getSrc(1)->emit(Func); | 2212 this->getSrc(1)->emit(Func); |
| 2251 } | 2213 } |
| 2252 | 2214 |
| 2253 template <class Machine> | 2215 template <class Machine> |
| 2254 void InstX86StoreQ<Machine>::emitIAS(const Cfg *Func) const { | 2216 void InstX86StoreQ<Machine>::emitIAS(const Cfg *Func) const { |
| 2255 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 2217 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 2256 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 2218 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 2257 assert(this->getSrcSize() == 2); | 2219 assert(this->getSrcSize() == 2); |
| 2258 const auto SrcVar = llvm::cast<Variable>(this->getSrc(0)); | 2220 const auto *SrcVar = llvm::cast<Variable>(this->getSrc(0)); |
| 2259 const auto DestMem = | 2221 const auto DestMem = |
| 2260 llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>( | 2222 llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>( |
| 2261 this->getSrc(1)); | 2223 this->getSrc(1)); |
| 2262 assert(DestMem->getSegmentRegister() == | 2224 assert(DestMem->getSegmentRegister() == |
| 2263 InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment); | 2225 InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment); |
| 2264 assert(SrcVar->hasReg()); | 2226 assert(SrcVar->hasReg()); |
| 2265 Asm->movq(DestMem->toAsmAddress(Asm), | 2227 Asm->movq(DestMem->toAsmAddress(Asm), |
| 2266 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( | 2228 InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum())); |
| 2267 SrcVar->getRegNum())); | |
| 2268 } | 2229 } |
| 2269 | 2230 |
| 2270 template <class Machine> | 2231 template <class Machine> |
| 2271 void InstX86StoreQ<Machine>::dump(const Cfg *Func) const { | 2232 void InstX86StoreQ<Machine>::dump(const Cfg *Func) const { |
| 2272 if (!BuildDefs::dump()) | 2233 if (!BuildDefs::dump()) |
| 2273 return; | 2234 return; |
| 2274 Ostream &Str = Func->getContext()->getStrDump(); | 2235 Ostream &Str = Func->getContext()->getStrDump(); |
| 2275 Str << "storeq." << this->getSrc(0)->getType() << " "; | 2236 Str << "storeq." << this->getSrc(0)->getType() << " "; |
| 2276 this->getSrc(1)->dump(Func); | 2237 this->getSrc(1)->dump(Func); |
| 2277 Str << ", "; | 2238 Str << ", "; |
| 2278 this->getSrc(0)->dump(Func); | 2239 this->getSrc(0)->dump(Func); |
| 2279 } | 2240 } |
| 2280 | 2241 |
| 2281 template <class Machine> void InstX86Lea<Machine>::emit(const Cfg *Func) const { | 2242 template <class Machine> void InstX86Lea<Machine>::emit(const Cfg *Func) const { |
| 2282 if (!BuildDefs::dump()) | 2243 if (!BuildDefs::dump()) |
| 2283 return; | 2244 return; |
| 2284 Ostream &Str = Func->getContext()->getStrEmit(); | 2245 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2285 assert(this->getSrcSize() == 1); | 2246 assert(this->getSrcSize() == 1); |
| 2286 assert(this->getDest()->hasReg()); | 2247 assert(this->getDest()->hasReg()); |
| 2287 Str << "\tleal\t"; | 2248 Str << "\tleal\t"; |
| 2288 Operand *Src0 = this->getSrc(0); | 2249 Operand *Src0 = this->getSrc(0); |
| 2289 if (const auto Src0Var = llvm::dyn_cast<Variable>(Src0)) { | 2250 if (const auto *Src0Var = llvm::dyn_cast<Variable>(Src0)) { |
| 2290 Type Ty = Src0Var->getType(); | 2251 Type Ty = Src0Var->getType(); |
| 2291 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an | 2252 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an |
| 2292 // acceptable type. | 2253 // acceptable type. |
| 2293 Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty)->emit(Func); | 2254 Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty, Variable::NoRegister) |
| 2255 ->emit(Func); | |
| 2294 } else { | 2256 } else { |
| 2295 Src0->emit(Func); | 2257 Src0->emit(Func); |
| 2296 } | 2258 } |
| 2297 Str << ", "; | 2259 Str << ", "; |
| 2298 this->getDest()->emit(Func); | 2260 this->getDest()->emit(Func); |
| 2299 } | 2261 } |
| 2300 | 2262 |
| 2301 inline bool isIntegerConstant(const Operand *Op) { | 2263 inline bool isIntegerConstant(const Operand *Op) { |
| 2302 return llvm::isa<ConstantInteger32>(Op) || llvm::isa<ConstantInteger64>(Op); | 2264 return llvm::isa<ConstantInteger32>(Op) || llvm::isa<ConstantInteger64>(Op); |
| 2303 } | 2265 } |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 2327 // src. This works even for stack-allocated dest variables because | 2289 // src. This works even for stack-allocated dest variables because |
| 2328 // typeWidthOnStack() pads to a 4-byte boundary even if only a lower portion | 2290 // typeWidthOnStack() pads to a 4-byte boundary even if only a lower portion |
| 2329 // is used. | 2291 // is used. |
| 2330 // TODO: This assert disallows usages such as copying a floating | 2292 // TODO: This assert disallows usages such as copying a floating |
| 2331 // point value between a vector and a scalar (which movss is used for). Clean | 2293 // point value between a vector and a scalar (which movss is used for). Clean |
| 2332 // this up. | 2294 // this up. |
| 2333 assert(Func->getTarget()->typeWidthInBytesOnStack(DestTy) == | 2295 assert(Func->getTarget()->typeWidthInBytesOnStack(DestTy) == |
| 2334 Func->getTarget()->typeWidthInBytesOnStack(SrcTy)); | 2296 Func->getTarget()->typeWidthInBytesOnStack(SrcTy)); |
| 2335 Src->emit(Func); | 2297 Src->emit(Func); |
| 2336 Str << ", "; | 2298 Str << ", "; |
| 2337 this->getDest()->asType(SrcTy)->emit(Func); | 2299 int32_t NewRegNum = Variable::NoRegister; |
| 2300 if (this->getDest()->hasReg()) | |
| 2301 NewRegNum = InstX86Base<Machine>::Traits::getGprForType( | |
| 2302 SrcTy, this->getDest()->getRegNum()); | |
| 2303 const Variable *NewDest = SrcTy == DestTy | |
| 2304 ? this->getDest() | |
| 2305 : this->getDest()->asType(SrcTy, NewRegNum); | |
| 2306 NewDest->emit(Func); | |
| 2338 } | 2307 } |
| 2339 | 2308 |
| 2340 template <class Machine> | 2309 template <class Machine> |
| 2341 void InstX86Mov<Machine>::emitIAS(const Cfg *Func) const { | 2310 void InstX86Mov<Machine>::emitIAS(const Cfg *Func) const { |
| 2342 assert(this->getSrcSize() == 1); | 2311 assert(this->getSrcSize() == 1); |
| 2343 const Variable *Dest = this->getDest(); | 2312 const Variable *Dest = this->getDest(); |
| 2344 const Operand *Src = this->getSrc(0); | 2313 const Operand *Src = this->getSrc(0); |
| 2345 Type DestTy = Dest->getType(); | 2314 Type DestTy = Dest->getType(); |
| 2346 Type SrcTy = Src->getType(); | 2315 Type SrcTy = Src->getType(); |
| 2347 // Mov can be used for GPRs or XMM registers. Also, the type does not | 2316 // Mov can be used for GPRs or XMM registers. Also, the type does not |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2384 // when both Src and Dest are integer types. | 2353 // when both Src and Dest are integer types. |
| 2385 if (InstX86Base<Machine>::Traits::Is64Bit && DestTy == IceType_i64 && | 2354 if (InstX86Base<Machine>::Traits::Is64Bit && DestTy == IceType_i64 && |
| 2386 isIntegerConstant(Src)) { | 2355 isIntegerConstant(Src)) { |
| 2387 uint64_t Value = -1; | 2356 uint64_t Value = -1; |
| 2388 if (const auto *C64 = llvm::dyn_cast<ConstantInteger64>(Src)) { | 2357 if (const auto *C64 = llvm::dyn_cast<ConstantInteger64>(Src)) { |
| 2389 Value = C64->getValue(); | 2358 Value = C64->getValue(); |
| 2390 } else { | 2359 } else { |
| 2391 Value = llvm::cast<ConstantInteger32>(Src)->getValue(); | 2360 Value = llvm::cast<ConstantInteger32>(Src)->getValue(); |
| 2392 } | 2361 } |
| 2393 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>() | 2362 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>() |
| 2394 ->movabs(InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | 2363 ->movabs( |
| 2395 Dest->getRegNum()), | 2364 InstX86Base<Machine>::Traits::getEncodedGPR(Dest->getRegNum()), |
| 2396 Value); | 2365 Value); |
| 2397 return; | 2366 return; |
| 2398 } | 2367 } |
| 2399 if (isScalarIntegerType(SrcTy)) { | 2368 if (isScalarIntegerType(SrcTy)) { |
| 2400 DestTy = SrcTy; | 2369 DestTy = SrcTy; |
| 2401 } | 2370 } |
| 2402 emitIASRegOpTyGPR<Machine>(Func, DestTy, Dest, Src, GPRRegEmitter); | 2371 emitIASRegOpTyGPR<Machine>(Func, DestTy, Dest, Src, GPRRegEmitter); |
| 2403 return; | 2372 return; |
| 2404 } | 2373 } |
| 2405 } else { | 2374 } else { |
| 2406 // Dest must be Stack and Src *could* be a register. Use Src's type to | 2375 // Dest must be Stack and Src *could* be a register. Use Src's type to |
| 2407 // decide on the emitters. | 2376 // decide on the emitters. |
| 2408 typename InstX86Base<Machine>::Traits::Address StackAddr( | 2377 typename InstX86Base<Machine>::Traits::Address StackAddr( |
| 2409 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 2378 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 2410 Func->getTarget()) | 2379 Func->getTarget()) |
| 2411 ->stackVarToAsmOperand(Dest)); | 2380 ->stackVarToAsmOperand(Dest)); |
| 2412 if (isScalarFloatingType(SrcTy)) { | 2381 if (isScalarFloatingType(SrcTy)) { |
| 2413 // Src must be a register. | 2382 // Src must be a register. |
| 2414 const auto SrcVar = llvm::cast<Variable>(Src); | 2383 const auto *SrcVar = llvm::cast<Variable>(Src); |
| 2415 assert(SrcVar->hasReg()); | 2384 assert(SrcVar->hasReg()); |
| 2416 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 2385 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 2417 Func->getAssembler< | 2386 Func->getAssembler< |
| 2418 typename InstX86Base<Machine>::Traits::Assembler>(); | 2387 typename InstX86Base<Machine>::Traits::Assembler>(); |
| 2419 Asm->movss(SrcTy, StackAddr, | 2388 Asm->movss(SrcTy, StackAddr, InstX86Base<Machine>::Traits::getEncodedXmm( |
| 2420 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( | 2389 SrcVar->getRegNum())); |
| 2421 SrcVar->getRegNum())); | |
| 2422 return; | 2390 return; |
| 2423 } else { | 2391 } else { |
| 2424 // Src can be a register or immediate. | 2392 // Src can be a register or immediate. |
| 2425 assert(isScalarIntegerType(SrcTy)); | 2393 assert(isScalarIntegerType(SrcTy)); |
| 2426 emitIASAddrOpTyGPR<Machine>(Func, SrcTy, StackAddr, Src, GPRAddrEmitter); | 2394 emitIASAddrOpTyGPR<Machine>(Func, SrcTy, StackAddr, Src, GPRAddrEmitter); |
| 2427 return; | 2395 return; |
| 2428 } | 2396 } |
| 2429 return; | 2397 return; |
| 2430 } | 2398 } |
| 2431 } | 2399 } |
| 2432 | 2400 |
| 2433 template <class Machine> | 2401 template <class Machine> |
| 2434 void InstX86Movd<Machine>::emitIAS(const Cfg *Func) const { | 2402 void InstX86Movd<Machine>::emitIAS(const Cfg *Func) const { |
| 2435 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 2403 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 2436 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 2404 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 2437 assert(this->getSrcSize() == 1); | 2405 assert(this->getSrcSize() == 1); |
| 2438 const Variable *Dest = this->getDest(); | 2406 const Variable *Dest = this->getDest(); |
| 2439 const auto SrcVar = llvm::cast<Variable>(this->getSrc(0)); | 2407 const auto *SrcVar = llvm::cast<Variable>(this->getSrc(0)); |
| 2440 // For insert/extract element (one of Src/Dest is an Xmm vector and the other | 2408 // For insert/extract element (one of Src/Dest is an Xmm vector and the other |
| 2441 // is an int type). | 2409 // is an int type). |
| 2442 if (SrcVar->getType() == IceType_i32 || | 2410 if (SrcVar->getType() == IceType_i32 || |
| 2443 (InstX86Base<Machine>::Traits::Is64Bit && | 2411 (InstX86Base<Machine>::Traits::Is64Bit && |
| 2444 SrcVar->getType() == IceType_i64)) { | 2412 SrcVar->getType() == IceType_i64)) { |
| 2445 assert(isVectorType(Dest->getType()) || | 2413 assert(isVectorType(Dest->getType()) || |
| 2446 (isScalarFloatingType(Dest->getType()) && | 2414 (isScalarFloatingType(Dest->getType()) && |
| 2447 typeWidthInBytes(SrcVar->getType()) == | 2415 typeWidthInBytes(SrcVar->getType()) == |
| 2448 typeWidthInBytes(Dest->getType()))); | 2416 typeWidthInBytes(Dest->getType()))); |
| 2449 assert(Dest->hasReg()); | 2417 assert(Dest->hasReg()); |
| 2450 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister DestReg = | 2418 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister DestReg = |
| 2451 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( | 2419 InstX86Base<Machine>::Traits::getEncodedXmm(Dest->getRegNum()); |
| 2452 Dest->getRegNum()); | |
| 2453 if (SrcVar->hasReg()) { | 2420 if (SrcVar->hasReg()) { |
| 2454 Asm->movd(SrcVar->getType(), DestReg, | 2421 Asm->movd( |
| 2455 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | 2422 SrcVar->getType(), DestReg, |
| 2456 SrcVar->getRegNum())); | 2423 InstX86Base<Machine>::Traits::getEncodedGPR(SrcVar->getRegNum())); |
| 2457 } else { | 2424 } else { |
| 2458 typename InstX86Base<Machine>::Traits::Address StackAddr( | 2425 typename InstX86Base<Machine>::Traits::Address StackAddr( |
| 2459 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 2426 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 2460 Func->getTarget()) | 2427 Func->getTarget()) |
| 2461 ->stackVarToAsmOperand(SrcVar)); | 2428 ->stackVarToAsmOperand(SrcVar)); |
| 2462 Asm->movd(SrcVar->getType(), DestReg, StackAddr); | 2429 Asm->movd(SrcVar->getType(), DestReg, StackAddr); |
| 2463 } | 2430 } |
| 2464 } else { | 2431 } else { |
| 2465 assert(isVectorType(SrcVar->getType()) || | 2432 assert(isVectorType(SrcVar->getType()) || |
| 2466 (isScalarFloatingType(SrcVar->getType()) && | 2433 (isScalarFloatingType(SrcVar->getType()) && |
| 2467 typeWidthInBytes(SrcVar->getType()) == | 2434 typeWidthInBytes(SrcVar->getType()) == |
| 2468 typeWidthInBytes(Dest->getType()))); | 2435 typeWidthInBytes(Dest->getType()))); |
| 2469 assert(SrcVar->hasReg()); | 2436 assert(SrcVar->hasReg()); |
| 2470 assert(Dest->getType() == IceType_i32 || | 2437 assert(Dest->getType() == IceType_i32 || |
| 2471 (InstX86Base<Machine>::Traits::Is64Bit && | 2438 (InstX86Base<Machine>::Traits::Is64Bit && |
| 2472 Dest->getType() == IceType_i64)); | 2439 Dest->getType() == IceType_i64)); |
| 2473 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg = | 2440 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg = |
| 2474 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( | 2441 InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum()); |
| 2475 SrcVar->getRegNum()); | |
| 2476 if (Dest->hasReg()) { | 2442 if (Dest->hasReg()) { |
| 2477 Asm->movd(Dest->getType(), | 2443 Asm->movd(Dest->getType(), |
| 2478 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | 2444 InstX86Base<Machine>::Traits::getEncodedGPR(Dest->getRegNum()), |
| 2479 Dest->getRegNum()), | |
| 2480 SrcReg); | 2445 SrcReg); |
| 2481 } else { | 2446 } else { |
| 2482 typename InstX86Base<Machine>::Traits::Address StackAddr( | 2447 typename InstX86Base<Machine>::Traits::Address StackAddr( |
| 2483 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 2448 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 2484 Func->getTarget()) | 2449 Func->getTarget()) |
| 2485 ->stackVarToAsmOperand(Dest)); | 2450 ->stackVarToAsmOperand(Dest)); |
| 2486 Asm->movd(Dest->getType(), StackAddr, SrcReg); | 2451 Asm->movd(Dest->getType(), StackAddr, SrcReg); |
| 2487 } | 2452 } |
| 2488 } | 2453 } |
| 2489 } | 2454 } |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2546 emitIASMovlikeXMM<Machine>(Func, Dest, Src, Emitter); | 2511 emitIASMovlikeXMM<Machine>(Func, Dest, Src, Emitter); |
| 2547 } | 2512 } |
| 2548 | 2513 |
| 2549 template <class Machine> | 2514 template <class Machine> |
| 2550 void InstX86MovssRegs<Machine>::emitIAS(const Cfg *Func) const { | 2515 void InstX86MovssRegs<Machine>::emitIAS(const Cfg *Func) const { |
| 2551 // This is Binop variant is only intended to be used for reg-reg moves where | 2516 // This is Binop variant is only intended to be used for reg-reg moves where |
| 2552 // part of the Dest register is untouched. | 2517 // part of the Dest register is untouched. |
| 2553 assert(this->getSrcSize() == 2); | 2518 assert(this->getSrcSize() == 2); |
| 2554 const Variable *Dest = this->getDest(); | 2519 const Variable *Dest = this->getDest(); |
| 2555 assert(Dest == this->getSrc(0)); | 2520 assert(Dest == this->getSrc(0)); |
| 2556 const auto SrcVar = llvm::cast<Variable>(this->getSrc(1)); | 2521 const auto *SrcVar = llvm::cast<Variable>(this->getSrc(1)); |
| 2557 assert(Dest->hasReg() && SrcVar->hasReg()); | 2522 assert(Dest->hasReg() && SrcVar->hasReg()); |
| 2558 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 2523 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 2559 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 2524 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 2560 Asm->movss(IceType_f32, | 2525 Asm->movss(IceType_f32, |
| 2561 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( | 2526 InstX86Base<Machine>::Traits::getEncodedXmm(Dest->getRegNum()), |
| 2562 Dest->getRegNum()), | 2527 InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum())); |
| 2563 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( | |
| 2564 SrcVar->getRegNum())); | |
| 2565 } | 2528 } |
| 2566 | 2529 |
| 2567 template <class Machine> | 2530 template <class Machine> |
| 2568 void InstX86Movsx<Machine>::emitIAS(const Cfg *Func) const { | 2531 void InstX86Movsx<Machine>::emitIAS(const Cfg *Func) const { |
| 2569 assert(this->getSrcSize() == 1); | 2532 assert(this->getSrcSize() == 1); |
| 2570 const Variable *Dest = this->getDest(); | 2533 const Variable *Dest = this->getDest(); |
| 2571 const Operand *Src = this->getSrc(0); | 2534 const Operand *Src = this->getSrc(0); |
| 2572 // Dest must be a > 8-bit register, but Src can be 8-bit. In practice we just | 2535 // Dest must be a > 8-bit register, but Src can be 8-bit. In practice we just |
| 2573 // use the full register for Dest to avoid having an OperandSizeOverride | 2536 // use the full register for Dest to avoid having an OperandSizeOverride |
| 2574 // prefix. It also allows us to only dispatch on SrcTy. | 2537 // prefix. It also allows us to only dispatch on SrcTy. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2614 Str << "nop (variant = " << Variant << ")"; | 2577 Str << "nop (variant = " << Variant << ")"; |
| 2615 } | 2578 } |
| 2616 | 2579 |
| 2617 template <class Machine> void InstX86Fld<Machine>::emit(const Cfg *Func) const { | 2580 template <class Machine> void InstX86Fld<Machine>::emit(const Cfg *Func) const { |
| 2618 if (!BuildDefs::dump()) | 2581 if (!BuildDefs::dump()) |
| 2619 return; | 2582 return; |
| 2620 Ostream &Str = Func->getContext()->getStrEmit(); | 2583 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2621 assert(this->getSrcSize() == 1); | 2584 assert(this->getSrcSize() == 1); |
| 2622 Type Ty = this->getSrc(0)->getType(); | 2585 Type Ty = this->getSrc(0)->getType(); |
| 2623 SizeT Width = typeWidthInBytes(Ty); | 2586 SizeT Width = typeWidthInBytes(Ty); |
| 2624 const auto Var = llvm::dyn_cast<Variable>(this->getSrc(0)); | 2587 const auto *Var = llvm::dyn_cast<Variable>(this->getSrc(0)); |
| 2625 if (Var && Var->hasReg()) { | 2588 if (Var && Var->hasReg()) { |
| 2626 // This is a physical xmm register, so we need to spill it to a temporary | 2589 // This is a physical xmm register, so we need to spill it to a temporary |
| 2627 // stack slot. | 2590 // stack slot. |
| 2628 Str << "\tsubl\t$" << Width << ", %esp" | 2591 Str << "\tsubl\t$" << Width << ", %esp" |
| 2629 << "\n"; | 2592 << "\n"; |
| 2630 Str << "\tmov" | 2593 Str << "\tmov" |
| 2631 << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString << "\t"; | 2594 << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString << "\t"; |
| 2632 Var->emit(Func); | 2595 Var->emit(Func); |
| 2633 Str << ", (%esp)\n"; | 2596 Str << ", (%esp)\n"; |
| 2634 Str << "\tfld" << this->getFldString(Ty) << "\t" | 2597 Str << "\tfld" << this->getFldString(Ty) << "\t" |
| 2635 << "(%esp)\n"; | 2598 << "(%esp)\n"; |
| 2636 Str << "\taddl\t$" << Width << ", %esp"; | 2599 Str << "\taddl\t$" << Width << ", %esp"; |
| 2637 return; | 2600 return; |
| 2638 } | 2601 } |
| 2639 Str << "\tfld" << this->getFldString(Ty) << "\t"; | 2602 Str << "\tfld" << this->getFldString(Ty) << "\t"; |
| 2640 this->getSrc(0)->emit(Func); | 2603 this->getSrc(0)->emit(Func); |
| 2641 } | 2604 } |
| 2642 | 2605 |
| 2643 template <class Machine> | 2606 template <class Machine> |
| 2644 void InstX86Fld<Machine>::emitIAS(const Cfg *Func) const { | 2607 void InstX86Fld<Machine>::emitIAS(const Cfg *Func) const { |
| 2645 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 2608 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 2646 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 2609 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 2647 assert(this->getSrcSize() == 1); | 2610 assert(this->getSrcSize() == 1); |
| 2648 const Operand *Src = this->getSrc(0); | 2611 const Operand *Src = this->getSrc(0); |
| 2649 Type Ty = Src->getType(); | 2612 Type Ty = Src->getType(); |
| 2650 if (const auto Var = llvm::dyn_cast<Variable>(Src)) { | 2613 if (const auto *Var = llvm::dyn_cast<Variable>(Src)) { |
| 2651 if (Var->hasReg()) { | 2614 if (Var->hasReg()) { |
| 2652 // This is a physical xmm register, so we need to spill it to a temporary | 2615 // This is a physical xmm register, so we need to spill it to a temporary |
| 2653 // stack slot. | 2616 // stack slot. |
| 2654 Immediate Width(typeWidthInBytes(Ty)); | 2617 Immediate Width(typeWidthInBytes(Ty)); |
| 2655 Asm->sub(IceType_i32, | 2618 Asm->sub(IceType_i32, |
| 2656 InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp, | 2619 InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp, |
| 2657 Width); | 2620 Width); |
| 2658 typename InstX86Base<Machine>::Traits::Address StackSlot = | 2621 typename InstX86Base<Machine>::Traits::Address StackSlot = |
| 2659 typename InstX86Base<Machine>::Traits::Address( | 2622 typename InstX86Base<Machine>::Traits::Address( |
| 2660 InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp, 0, | 2623 InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp, 0, |
| 2661 AssemblerFixup::NoFixup); | 2624 AssemblerFixup::NoFixup); |
| 2662 Asm->movss(Ty, StackSlot, | 2625 Asm->movss(Ty, StackSlot, |
| 2663 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( | 2626 InstX86Base<Machine>::Traits::getEncodedXmm(Var->getRegNum())); |
| 2664 Var->getRegNum())); | |
| 2665 Asm->fld(Ty, StackSlot); | 2627 Asm->fld(Ty, StackSlot); |
| 2666 Asm->add(IceType_i32, | 2628 Asm->add(IceType_i32, |
| 2667 InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp, | 2629 InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp, |
| 2668 Width); | 2630 Width); |
| 2669 } else { | 2631 } else { |
| 2670 typename InstX86Base<Machine>::Traits::Address StackAddr( | 2632 typename InstX86Base<Machine>::Traits::Address StackAddr( |
| 2671 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 2633 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 2672 Func->getTarget()) | 2634 Func->getTarget()) |
| 2673 ->stackVarToAsmOperand(Var)); | 2635 ->stackVarToAsmOperand(Var)); |
| 2674 Asm->fld(Ty, StackAddr); | 2636 Asm->fld(Ty, StackAddr); |
| 2675 } | 2637 } |
| 2676 } else if (const auto Mem = llvm::dyn_cast< | 2638 } else if (const auto *Mem = llvm::dyn_cast< |
| 2677 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) { | 2639 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) { |
| 2678 assert(Mem->getSegmentRegister() == | 2640 assert(Mem->getSegmentRegister() == |
| 2679 InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment); | 2641 InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment); |
| 2680 Asm->fld(Ty, Mem->toAsmAddress(Asm)); | 2642 Asm->fld(Ty, Mem->toAsmAddress(Asm)); |
| 2681 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { | 2643 } else if (const auto *Imm = llvm::dyn_cast<Constant>(Src)) { |
| 2682 Asm->fld(Ty, InstX86Base<Machine>::Traits::Address::ofConstPool(Asm, Imm)); | 2644 Asm->fld(Ty, InstX86Base<Machine>::Traits::Address::ofConstPool(Asm, Imm)); |
| 2683 } else { | 2645 } else { |
| 2684 llvm_unreachable("Unexpected operand type"); | 2646 llvm_unreachable("Unexpected operand type"); |
| 2685 } | 2647 } |
| 2686 } | 2648 } |
| 2687 | 2649 |
| 2688 template <class Machine> void InstX86Fld<Machine>::dump(const Cfg *Func) const { | 2650 template <class Machine> void InstX86Fld<Machine>::dump(const Cfg *Func) const { |
| 2689 if (!BuildDefs::dump()) | 2651 if (!BuildDefs::dump()) |
| 2690 return; | 2652 return; |
| 2691 Ostream &Str = Func->getContext()->getStrDump(); | 2653 Ostream &Str = Func->getContext()->getStrDump(); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2752 // Hack this by creating a temporary stack slot, spilling st(0) there, | 2714 // Hack this by creating a temporary stack slot, spilling st(0) there, |
| 2753 // loading it into the xmm register, and deallocating the stack slot. | 2715 // loading it into the xmm register, and deallocating the stack slot. |
| 2754 Immediate Width(typeWidthInBytes(Ty)); | 2716 Immediate Width(typeWidthInBytes(Ty)); |
| 2755 Asm->sub(IceType_i32, | 2717 Asm->sub(IceType_i32, |
| 2756 InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp, Width); | 2718 InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp, Width); |
| 2757 typename InstX86Base<Machine>::Traits::Address StackSlot = | 2719 typename InstX86Base<Machine>::Traits::Address StackSlot = |
| 2758 typename InstX86Base<Machine>::Traits::Address( | 2720 typename InstX86Base<Machine>::Traits::Address( |
| 2759 InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp, 0, | 2721 InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp, 0, |
| 2760 AssemblerFixup::NoFixup); | 2722 AssemblerFixup::NoFixup); |
| 2761 Asm->fstp(Ty, StackSlot); | 2723 Asm->fstp(Ty, StackSlot); |
| 2762 Asm->movss(Ty, InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( | 2724 Asm->movss(Ty, |
| 2763 Dest->getRegNum()), | 2725 InstX86Base<Machine>::Traits::getEncodedXmm(Dest->getRegNum()), |
| 2764 StackSlot); | 2726 StackSlot); |
| 2765 Asm->add(IceType_i32, | 2727 Asm->add(IceType_i32, |
| 2766 InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp, Width); | 2728 InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp, Width); |
| 2767 } | 2729 } |
| 2768 } | 2730 } |
| 2769 | 2731 |
| 2770 template <class Machine> | 2732 template <class Machine> |
| 2771 void InstX86Fstp<Machine>::dump(const Cfg *Func) const { | 2733 void InstX86Fstp<Machine>::dump(const Cfg *Func) const { |
| 2772 if (!BuildDefs::dump()) | 2734 if (!BuildDefs::dump()) |
| 2773 return; | 2735 return; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2818 .PackString << "\t"; | 2780 .PackString << "\t"; |
| 2819 this->getSrc(1)->emit(Func); | 2781 this->getSrc(1)->emit(Func); |
| 2820 Str << ", "; | 2782 Str << ", "; |
| 2821 this->getSrc(0)->emit(Func); | 2783 this->getSrc(0)->emit(Func); |
| 2822 Str << ", "; | 2784 Str << ", "; |
| 2823 Variable *Dest = this->getDest(); | 2785 Variable *Dest = this->getDest(); |
| 2824 // pextrw must take a register dest. There is an SSE4.1 version that takes a | 2786 // pextrw must take a register dest. There is an SSE4.1 version that takes a |
| 2825 // memory dest, but we aren't using it. For uniformity, just restrict them | 2787 // memory dest, but we aren't using it. For uniformity, just restrict them |
| 2826 // all to have a register dest for now. | 2788 // all to have a register dest for now. |
| 2827 assert(Dest->hasReg()); | 2789 assert(Dest->hasReg()); |
| 2828 Dest->asType(IceType_i32)->emit(Func); | 2790 Dest->asType(IceType_i32, Dest->getRegNum())->emit(Func); |
| 2829 } | 2791 } |
| 2830 | 2792 |
| 2831 template <class Machine> | 2793 template <class Machine> |
| 2832 void InstX86Pextr<Machine>::emitIAS(const Cfg *Func) const { | 2794 void InstX86Pextr<Machine>::emitIAS(const Cfg *Func) const { |
| 2833 assert(this->getSrcSize() == 2); | 2795 assert(this->getSrcSize() == 2); |
| 2834 // pextrb and pextrd are SSE4.1 instructions. | 2796 // pextrb and pextrd are SSE4.1 instructions. |
| 2835 const Variable *Dest = this->getDest(); | 2797 const Variable *Dest = this->getDest(); |
| 2836 Type DispatchTy = Dest->getType(); | 2798 Type DispatchTy = InstX86Base<Machine>::Traits::getInVectorElementType( |
| 2799 this->getSrc(0)->getType()); | |
| 2837 assert(DispatchTy == IceType_i16 || | 2800 assert(DispatchTy == IceType_i16 || |
| 2838 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 2801 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 2839 Func->getTarget()) | 2802 Func->getTarget()) |
| 2840 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1); | 2803 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1); |
| 2841 // pextrw must take a register dest. There is an SSE4.1 version that takes a | 2804 // pextrw must take a register dest. There is an SSE4.1 version that takes a |
| 2842 // memory dest, but we aren't using it. For uniformity, just restrict them | 2805 // memory dest, but we aren't using it. For uniformity, just restrict them |
| 2843 // all to have a register dest for now. | 2806 // all to have a register dest for now. |
| 2844 assert(Dest->hasReg()); | 2807 assert(Dest->hasReg()); |
| 2845 // pextrw's Src(0) must be a register (both SSE4.1 and SSE2). | 2808 // pextrw's Src(0) must be a register (both SSE4.1 and SSE2). |
| 2846 assert(llvm::cast<Variable>(this->getSrc(0))->hasReg()); | 2809 assert(llvm::cast<Variable>(this->getSrc(0))->hasReg()); |
| 2847 static const typename InstX86Base<Machine>::Traits::Assembler:: | 2810 static const typename InstX86Base<Machine>::Traits::Assembler:: |
| 2848 template ThreeOpImmEmitter< | 2811 template ThreeOpImmEmitter< |
| 2849 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, | 2812 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, |
| 2850 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister> | 2813 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister> |
| 2851 Emitter = {&InstX86Base<Machine>::Traits::Assembler::pextr, nullptr}; | 2814 Emitter = {&InstX86Base<Machine>::Traits::Assembler::pextr, nullptr}; |
| 2852 emitIASThreeOpImmOps< | 2815 emitIASThreeOpImmOps< |
| 2853 Machine, typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, | 2816 Machine, typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, |
| 2854 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, | 2817 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, |
| 2855 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR, | 2818 InstX86Base<Machine>::Traits::getEncodedGPR, |
| 2856 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm>( | 2819 InstX86Base<Machine>::Traits::getEncodedXmm>( |
| 2857 Func, DispatchTy, Dest, this->getSrc(0), this->getSrc(1), Emitter); | 2820 Func, DispatchTy, Dest, this->getSrc(0), this->getSrc(1), Emitter); |
| 2858 } | 2821 } |
| 2859 | 2822 |
| 2860 template <class Machine> | 2823 template <class Machine> |
| 2861 void InstX86Pinsr<Machine>::emit(const Cfg *Func) const { | 2824 void InstX86Pinsr<Machine>::emit(const Cfg *Func) const { |
| 2862 if (!BuildDefs::dump()) | 2825 if (!BuildDefs::dump()) |
| 2863 return; | 2826 return; |
| 2864 Ostream &Str = Func->getContext()->getStrEmit(); | 2827 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2865 assert(this->getSrcSize() == 3); | 2828 assert(this->getSrcSize() == 3); |
| 2866 // pinsrb and pinsrd are SSE4.1 instructions. | 2829 // pinsrb and pinsrd are SSE4.1 instructions. |
| 2867 assert(this->getDest()->getType() == IceType_v8i16 || | 2830 assert(this->getDest()->getType() == IceType_v8i16 || |
| 2868 this->getDest()->getType() == IceType_v8i1 || | 2831 this->getDest()->getType() == IceType_v8i1 || |
| 2869 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 2832 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 2870 Func->getTarget()) | 2833 Func->getTarget()) |
| 2871 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1); | 2834 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1); |
| 2872 Str << "\t" << this->Opcode | 2835 Str << "\t" << this->Opcode |
| 2873 << InstX86Base< | 2836 << InstX86Base< |
| 2874 Machine>::Traits::TypeAttributes[this->getDest()->getType()] | 2837 Machine>::Traits::TypeAttributes[this->getDest()->getType()] |
| 2875 .PackString << "\t"; | 2838 .PackString << "\t"; |
| 2876 this->getSrc(2)->emit(Func); | 2839 this->getSrc(2)->emit(Func); |
| 2877 Str << ", "; | 2840 Str << ", "; |
| 2878 Operand *Src1 = this->getSrc(1); | 2841 Operand *Src1 = this->getSrc(1); |
| 2879 if (const auto Src1Var = llvm::dyn_cast<Variable>(Src1)) { | 2842 if (const auto *Src1Var = llvm::dyn_cast<Variable>(Src1)) { |
| 2880 // If src1 is a register, it should always be r32. | 2843 // If src1 is a register, it should always be r32. |
| 2881 if (Src1Var->hasReg()) { | 2844 if (Src1Var->hasReg()) { |
| 2882 Src1Var->asType(IceType_i32)->emit(Func); | 2845 int32_t NewRegNum = |
| 2846 InstX86Base<Machine>::Traits::getBaseReg(Src1Var->getRegNum()); | |
| 2847 const Variable *NewSrc = Src1Var->asType(IceType_i32, NewRegNum); | |
| 2848 NewSrc->emit(Func); | |
| 2883 } else { | 2849 } else { |
| 2884 Src1Var->emit(Func); | 2850 Src1Var->emit(Func); |
| 2885 } | 2851 } |
| 2886 } else { | 2852 } else { |
| 2887 Src1->emit(Func); | 2853 Src1->emit(Func); |
| 2888 } | 2854 } |
| 2889 Str << ", "; | 2855 Str << ", "; |
| 2890 this->getDest()->emit(Func); | 2856 this->getDest()->emit(Func); |
| 2891 } | 2857 } |
| 2892 | 2858 |
| 2893 template <class Machine> | 2859 template <class Machine> |
| 2894 void InstX86Pinsr<Machine>::emitIAS(const Cfg *Func) const { | 2860 void InstX86Pinsr<Machine>::emitIAS(const Cfg *Func) const { |
| 2895 assert(this->getSrcSize() == 3); | 2861 assert(this->getSrcSize() == 3); |
| 2896 assert(this->getDest() == this->getSrc(0)); | 2862 assert(this->getDest() == this->getSrc(0)); |
| 2897 // pinsrb and pinsrd are SSE4.1 instructions. | 2863 // pinsrb and pinsrd are SSE4.1 instructions. |
| 2898 const Operand *Src0 = this->getSrc(1); | 2864 const Operand *Src0 = this->getSrc(1); |
| 2899 Type DispatchTy = Src0->getType(); | 2865 Type DispatchTy = Src0->getType(); |
| 2900 assert(DispatchTy == IceType_i16 || | 2866 assert(DispatchTy == IceType_i16 || |
| 2901 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 2867 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 2902 Func->getTarget()) | 2868 Func->getTarget()) |
| 2903 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1); | 2869 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1); |
| 2904 // If src1 is a register, it should always be r32 (this should fall out from | 2870 // If src1 is a register, it should always be r32 (this should fall out from |
| 2905 // the encodings for ByteRegs overlapping the encodings for r32), but we have | 2871 // the encodings for ByteRegs overlapping the encodings for r32), but we have |
| 2906 // to trust the regalloc to not choose "ah", where it doesn't overlap. | 2872 // to make sure the register allocator didn't choose an 8-bit high register |
| 2873 // like "ah". | |
| 2874 if (BuildDefs::asserts()) { | |
| 2875 if (auto *Src0Var = llvm::dyn_cast<Variable>(Src0)) { | |
| 2876 if (Src0Var->hasReg()) { | |
| 2877 int32_t RegNum = Src0Var->getRegNum(); | |
| 2878 int32_t BaseRegNum = InstX86Base<Machine>::Traits::getBaseReg(RegNum); | |
| 2879 (void)BaseRegNum; | |
| 2880 assert(InstX86Base<Machine>::Traits::getEncodedGPR(RegNum) == | |
| 2881 InstX86Base<Machine>::Traits::getEncodedGPR(BaseRegNum)); | |
| 2882 } | |
| 2883 } | |
| 2884 } | |
| 2907 static const typename InstX86Base<Machine>::Traits::Assembler:: | 2885 static const typename InstX86Base<Machine>::Traits::Assembler:: |
| 2908 template ThreeOpImmEmitter< | 2886 template ThreeOpImmEmitter< |
| 2909 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, | 2887 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, |
| 2910 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister> | 2888 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister> |
| 2911 Emitter = {&InstX86Base<Machine>::Traits::Assembler::pinsr, | 2889 Emitter = {&InstX86Base<Machine>::Traits::Assembler::pinsr, |
| 2912 &InstX86Base<Machine>::Traits::Assembler::pinsr}; | 2890 &InstX86Base<Machine>::Traits::Assembler::pinsr}; |
| 2913 emitIASThreeOpImmOps< | 2891 emitIASThreeOpImmOps< |
| 2914 Machine, typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, | 2892 Machine, typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, |
| 2915 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, | 2893 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, |
| 2916 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm, | 2894 InstX86Base<Machine>::Traits::getEncodedXmm, |
| 2917 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR>( | 2895 InstX86Base<Machine>::Traits::getEncodedGPR>( |
| 2918 Func, DispatchTy, this->getDest(), Src0, this->getSrc(2), Emitter); | 2896 Func, DispatchTy, this->getDest(), Src0, this->getSrc(2), Emitter); |
| 2919 } | 2897 } |
| 2920 | 2898 |
| 2921 template <class Machine> | 2899 template <class Machine> |
| 2922 void InstX86Pshufd<Machine>::emitIAS(const Cfg *Func) const { | 2900 void InstX86Pshufd<Machine>::emitIAS(const Cfg *Func) const { |
| 2923 assert(this->getSrcSize() == 2); | 2901 assert(this->getSrcSize() == 2); |
| 2924 const Variable *Dest = this->getDest(); | 2902 const Variable *Dest = this->getDest(); |
| 2925 Type Ty = Dest->getType(); | 2903 Type Ty = Dest->getType(); |
| 2926 static const typename InstX86Base<Machine>::Traits::Assembler:: | 2904 static const typename InstX86Base<Machine>::Traits::Assembler:: |
| 2927 template ThreeOpImmEmitter< | 2905 template ThreeOpImmEmitter< |
| 2928 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, | 2906 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, |
| 2929 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister> | 2907 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister> |
| 2930 Emitter = {&InstX86Base<Machine>::Traits::Assembler::pshufd, | 2908 Emitter = {&InstX86Base<Machine>::Traits::Assembler::pshufd, |
| 2931 &InstX86Base<Machine>::Traits::Assembler::pshufd}; | 2909 &InstX86Base<Machine>::Traits::Assembler::pshufd}; |
| 2932 emitIASThreeOpImmOps< | 2910 emitIASThreeOpImmOps< |
| 2933 Machine, typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, | 2911 Machine, typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, |
| 2934 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, | 2912 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, |
| 2935 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm, | 2913 InstX86Base<Machine>::Traits::getEncodedXmm, |
| 2936 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm>( | 2914 InstX86Base<Machine>::Traits::getEncodedXmm>( |
| 2937 Func, Ty, Dest, this->getSrc(0), this->getSrc(1), Emitter); | 2915 Func, Ty, Dest, this->getSrc(0), this->getSrc(1), Emitter); |
| 2938 } | 2916 } |
| 2939 | 2917 |
| 2940 template <class Machine> | 2918 template <class Machine> |
| 2941 void InstX86Shufps<Machine>::emitIAS(const Cfg *Func) const { | 2919 void InstX86Shufps<Machine>::emitIAS(const Cfg *Func) const { |
| 2942 assert(this->getSrcSize() == 3); | 2920 assert(this->getSrcSize() == 3); |
| 2943 const Variable *Dest = this->getDest(); | 2921 const Variable *Dest = this->getDest(); |
| 2944 assert(Dest == this->getSrc(0)); | 2922 assert(Dest == this->getSrc(0)); |
| 2945 Type Ty = Dest->getType(); | 2923 Type Ty = Dest->getType(); |
| 2946 static const typename InstX86Base<Machine>::Traits::Assembler:: | 2924 static const typename InstX86Base<Machine>::Traits::Assembler:: |
| 2947 template ThreeOpImmEmitter< | 2925 template ThreeOpImmEmitter< |
| 2948 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, | 2926 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, |
| 2949 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister> | 2927 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister> |
| 2950 Emitter = {&InstX86Base<Machine>::Traits::Assembler::shufps, | 2928 Emitter = {&InstX86Base<Machine>::Traits::Assembler::shufps, |
| 2951 &InstX86Base<Machine>::Traits::Assembler::shufps}; | 2929 &InstX86Base<Machine>::Traits::Assembler::shufps}; |
| 2952 emitIASThreeOpImmOps< | 2930 emitIASThreeOpImmOps< |
| 2953 Machine, typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, | 2931 Machine, typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, |
| 2954 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, | 2932 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, |
| 2955 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm, | 2933 InstX86Base<Machine>::Traits::getEncodedXmm, |
| 2956 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm>( | 2934 InstX86Base<Machine>::Traits::getEncodedXmm>( |
| 2957 Func, Ty, Dest, this->getSrc(1), this->getSrc(2), Emitter); | 2935 Func, Ty, Dest, this->getSrc(1), this->getSrc(2), Emitter); |
| 2958 } | 2936 } |
| 2959 | 2937 |
| 2960 template <class Machine> void InstX86Pop<Machine>::emit(const Cfg *Func) const { | 2938 template <class Machine> void InstX86Pop<Machine>::emit(const Cfg *Func) const { |
| 2961 if (!BuildDefs::dump()) | 2939 if (!BuildDefs::dump()) |
| 2962 return; | 2940 return; |
| 2963 Ostream &Str = Func->getContext()->getStrEmit(); | 2941 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2964 assert(this->getSrcSize() == 0); | 2942 assert(this->getSrcSize() == 0); |
| 2965 Str << "\tpop\t"; | 2943 Str << "\tpop\t"; |
| 2966 this->getDest()->emit(Func); | 2944 this->getDest()->emit(Func); |
| 2967 } | 2945 } |
| 2968 | 2946 |
| 2969 template <class Machine> | 2947 template <class Machine> |
| 2970 void InstX86Pop<Machine>::emitIAS(const Cfg *Func) const { | 2948 void InstX86Pop<Machine>::emitIAS(const Cfg *Func) const { |
| 2971 assert(this->getSrcSize() == 0); | 2949 assert(this->getSrcSize() == 0); |
| 2972 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 2950 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 2973 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 2951 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 2974 if (this->getDest()->hasReg()) { | 2952 if (this->getDest()->hasReg()) { |
| 2975 Asm->popl(InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | 2953 Asm->popl(InstX86Base<Machine>::Traits::getEncodedGPR( |
| 2976 this->getDest()->getRegNum())); | 2954 this->getDest()->getRegNum())); |
| 2977 } else { | 2955 } else { |
| 2978 Asm->popl( | 2956 Asm->popl( |
| 2979 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 2957 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 2980 Func->getTarget()) | 2958 Func->getTarget()) |
| 2981 ->stackVarToAsmOperand(this->getDest())); | 2959 ->stackVarToAsmOperand(this->getDest())); |
| 2982 } | 2960 } |
| 2983 } | 2961 } |
| 2984 | 2962 |
| 2985 template <class Machine> void InstX86Pop<Machine>::dump(const Cfg *Func) const { | 2963 template <class Machine> void InstX86Pop<Machine>::dump(const Cfg *Func) const { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3017 Str << "esp = sub.i32 esp, " << Amount; | 2995 Str << "esp = sub.i32 esp, " << Amount; |
| 3018 } | 2996 } |
| 3019 | 2997 |
| 3020 template <class Machine> | 2998 template <class Machine> |
| 3021 void InstX86Push<Machine>::emit(const Cfg *Func) const { | 2999 void InstX86Push<Machine>::emit(const Cfg *Func) const { |
| 3022 if (!BuildDefs::dump()) | 3000 if (!BuildDefs::dump()) |
| 3023 return; | 3001 return; |
| 3024 Ostream &Str = Func->getContext()->getStrEmit(); | 3002 Ostream &Str = Func->getContext()->getStrEmit(); |
| 3025 assert(this->getSrcSize() == 1); | 3003 assert(this->getSrcSize() == 1); |
| 3026 // Push is currently only used for saving GPRs. | 3004 // Push is currently only used for saving GPRs. |
| 3027 const auto Var = llvm::cast<Variable>(this->getSrc(0)); | 3005 const auto *Var = llvm::cast<Variable>(this->getSrc(0)); |
| 3028 assert(Var->hasReg()); | 3006 assert(Var->hasReg()); |
| 3029 Str << "\tpush\t"; | 3007 Str << "\tpush\t"; |
| 3030 Var->emit(Func); | 3008 Var->emit(Func); |
| 3031 } | 3009 } |
| 3032 | 3010 |
| 3033 template <class Machine> | 3011 template <class Machine> |
| 3034 void InstX86Push<Machine>::emitIAS(const Cfg *Func) const { | 3012 void InstX86Push<Machine>::emitIAS(const Cfg *Func) const { |
| 3035 assert(this->getSrcSize() == 1); | 3013 assert(this->getSrcSize() == 1); |
| 3036 // Push is currently only used for saving GPRs. | 3014 // Push is currently only used for saving GPRs. |
| 3037 const auto Var = llvm::cast<Variable>(this->getSrc(0)); | 3015 const auto *Var = llvm::cast<Variable>(this->getSrc(0)); |
| 3038 assert(Var->hasReg()); | 3016 assert(Var->hasReg()); |
| 3039 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 3017 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 3040 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 3018 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 3041 Asm->pushl(InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | 3019 Asm->pushl(InstX86Base<Machine>::Traits::getEncodedGPR(Var->getRegNum())); |
| 3042 Var->getRegNum())); | |
| 3043 } | 3020 } |
| 3044 | 3021 |
| 3045 template <class Machine> | 3022 template <class Machine> |
| 3046 void InstX86Push<Machine>::dump(const Cfg *Func) const { | 3023 void InstX86Push<Machine>::dump(const Cfg *Func) const { |
| 3047 if (!BuildDefs::dump()) | 3024 if (!BuildDefs::dump()) |
| 3048 return; | 3025 return; |
| 3049 Ostream &Str = Func->getContext()->getStrDump(); | 3026 Ostream &Str = Func->getContext()->getStrDump(); |
| 3050 Str << "push." << this->getSrc(0)->getType() << " "; | 3027 Str << "push." << this->getSrc(0)->getType() << " "; |
| 3051 this->dumpSources(Func); | 3028 this->dumpSources(Func); |
| 3052 } | 3029 } |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3131 } | 3108 } |
| 3132 | 3109 |
| 3133 template <class Machine> | 3110 template <class Machine> |
| 3134 void InstX86Setcc<Machine>::emitIAS(const Cfg *Func) const { | 3111 void InstX86Setcc<Machine>::emitIAS(const Cfg *Func) const { |
| 3135 assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None); | 3112 assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None); |
| 3136 assert(this->getDest()->getType() == IceType_i1); | 3113 assert(this->getDest()->getType() == IceType_i1); |
| 3137 assert(this->getSrcSize() == 0); | 3114 assert(this->getSrcSize() == 0); |
| 3138 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 3115 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 3139 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 3116 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 3140 if (this->getDest()->hasReg()) | 3117 if (this->getDest()->hasReg()) |
| 3141 Asm->setcc(Condition, | 3118 Asm->setcc(Condition, InstX86Base<Machine>::Traits::getEncodedByteReg( |
| 3142 InstX86Base<Machine>::Traits::RegisterSet::getEncodedByteReg( | 3119 this->getDest()->getRegNum())); |
| 3143 this->getDest()->getRegNum())); | |
| 3144 else | 3120 else |
| 3145 Asm->setcc( | 3121 Asm->setcc( |
| 3146 Condition, | 3122 Condition, |
| 3147 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 3123 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 3148 Func->getTarget()) | 3124 Func->getTarget()) |
| 3149 ->stackVarToAsmOperand(this->getDest())); | 3125 ->stackVarToAsmOperand(this->getDest())); |
| 3150 return; | 3126 return; |
| 3151 } | 3127 } |
| 3152 | 3128 |
| 3153 template <class Machine> | 3129 template <class Machine> |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 3181 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 3157 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 3182 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 3158 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 3183 Type Ty = this->getSrc(0)->getType(); | 3159 Type Ty = this->getSrc(0)->getType(); |
| 3184 const auto Mem = | 3160 const auto Mem = |
| 3185 llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>( | 3161 llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>( |
| 3186 this->getSrc(0)); | 3162 this->getSrc(0)); |
| 3187 assert(Mem->getSegmentRegister() == | 3163 assert(Mem->getSegmentRegister() == |
| 3188 InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment); | 3164 InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment); |
| 3189 const typename InstX86Base<Machine>::Traits::Address Addr = | 3165 const typename InstX86Base<Machine>::Traits::Address Addr = |
| 3190 Mem->toAsmAddress(Asm); | 3166 Mem->toAsmAddress(Asm); |
| 3191 const auto VarReg = llvm::cast<Variable>(this->getSrc(1)); | 3167 const auto *VarReg = llvm::cast<Variable>(this->getSrc(1)); |
| 3192 assert(VarReg->hasReg()); | 3168 assert(VarReg->hasReg()); |
| 3193 const typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister Reg = | 3169 const typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister Reg = |
| 3194 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | 3170 InstX86Base<Machine>::Traits::getEncodedGPR(VarReg->getRegNum()); |
| 3195 VarReg->getRegNum()); | |
| 3196 Asm->xadd(Ty, Addr, Reg, this->Locked); | 3171 Asm->xadd(Ty, Addr, Reg, this->Locked); |
| 3197 } | 3172 } |
| 3198 | 3173 |
| 3199 template <class Machine> | 3174 template <class Machine> |
| 3200 void InstX86Xadd<Machine>::dump(const Cfg *Func) const { | 3175 void InstX86Xadd<Machine>::dump(const Cfg *Func) const { |
| 3201 if (!BuildDefs::dump()) | 3176 if (!BuildDefs::dump()) |
| 3202 return; | 3177 return; |
| 3203 Ostream &Str = Func->getContext()->getStrDump(); | 3178 Ostream &Str = Func->getContext()->getStrDump(); |
| 3204 if (this->Locked) { | 3179 if (this->Locked) { |
| 3205 Str << "lock "; | 3180 Str << "lock "; |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 3222 | 3197 |
| 3223 template <class Machine> | 3198 template <class Machine> |
| 3224 void InstX86Xchg<Machine>::emitIAS(const Cfg *Func) const { | 3199 void InstX86Xchg<Machine>::emitIAS(const Cfg *Func) const { |
| 3225 assert(this->getSrcSize() == 2); | 3200 assert(this->getSrcSize() == 2); |
| 3226 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 3201 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 3227 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 3202 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 3228 Type Ty = this->getSrc(0)->getType(); | 3203 Type Ty = this->getSrc(0)->getType(); |
| 3229 const auto *VarReg1 = llvm::cast<Variable>(this->getSrc(1)); | 3204 const auto *VarReg1 = llvm::cast<Variable>(this->getSrc(1)); |
| 3230 assert(VarReg1->hasReg()); | 3205 assert(VarReg1->hasReg()); |
| 3231 const typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister Reg1 = | 3206 const typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister Reg1 = |
| 3232 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | 3207 InstX86Base<Machine>::Traits::getEncodedGPR(VarReg1->getRegNum()); |
| 3233 VarReg1->getRegNum()); | |
| 3234 | 3208 |
| 3235 if (const auto *VarReg0 = llvm::dyn_cast<Variable>(this->getSrc(0))) { | 3209 if (const auto *VarReg0 = llvm::dyn_cast<Variable>(this->getSrc(0))) { |
| 3236 assert(VarReg0->hasReg()); | 3210 assert(VarReg0->hasReg()); |
| 3237 const typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister Reg0 = | 3211 const typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister Reg0 = |
| 3238 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | 3212 InstX86Base<Machine>::Traits::getEncodedGPR(VarReg0->getRegNum()); |
| 3239 VarReg0->getRegNum()); | |
| 3240 Asm->xchg(Ty, Reg0, Reg1); | 3213 Asm->xchg(Ty, Reg0, Reg1); |
| 3241 return; | 3214 return; |
| 3242 } | 3215 } |
| 3243 | 3216 |
| 3244 const auto *Mem = | 3217 const auto *Mem = |
| 3245 llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>( | 3218 llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>( |
| 3246 this->getSrc(0)); | 3219 this->getSrc(0)); |
| 3247 assert(Mem->getSegmentRegister() == | 3220 assert(Mem->getSegmentRegister() == |
| 3248 InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment); | 3221 InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment); |
| 3249 const typename InstX86Base<Machine>::Traits::Address Addr = | 3222 const typename InstX86Base<Machine>::Traits::Address Addr = |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3311 return; | 3284 return; |
| 3312 Ostream &Str = Func->getContext()->getStrDump(); | 3285 Ostream &Str = Func->getContext()->getStrDump(); |
| 3313 Str << "IACA_END"; | 3286 Str << "IACA_END"; |
| 3314 } | 3287 } |
| 3315 | 3288 |
| 3316 } // end of namespace X86Internal | 3289 } // end of namespace X86Internal |
| 3317 | 3290 |
| 3318 } // end of namespace Ice | 3291 } // end of namespace Ice |
| 3319 | 3292 |
| 3320 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H | 3293 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H |
| OLD | NEW |