Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(84)

Side by Side Diff: src/IceInstX86BaseImpl.h

Issue 1419903002: Subzero: Refactor x86 register definitions to use the alias mechanism. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Bring back ByteRegister Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698