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