OLD | NEW |
1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// | 1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// |
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 // This file implements the InstX8632 and OperandX8632 classes, | 10 // This file implements the InstX8632 and OperandX8632 classes, |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 : InstX8632(Func, InstX8632::Mfence, 0, NULL) { | 260 : InstX8632(Func, InstX8632::Mfence, 0, NULL) { |
261 HasSideEffects = true; | 261 HasSideEffects = true; |
262 } | 262 } |
263 | 263 |
264 InstX8632Store::InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem) | 264 InstX8632Store::InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem) |
265 : InstX8632(Func, InstX8632::Store, 2, NULL) { | 265 : InstX8632(Func, InstX8632::Store, 2, NULL) { |
266 addSource(Value); | 266 addSource(Value); |
267 addSource(Mem); | 267 addSource(Mem); |
268 } | 268 } |
269 | 269 |
270 InstX8632StoreP::InstX8632StoreP(Cfg *Func, Operand *Value, OperandX8632 *Mem) | 270 InstX8632StoreP::InstX8632StoreP(Cfg *Func, Variable *Value, |
| 271 OperandX8632Mem *Mem) |
271 : InstX8632(Func, InstX8632::StoreP, 2, NULL) { | 272 : InstX8632(Func, InstX8632::StoreP, 2, NULL) { |
272 addSource(Value); | 273 addSource(Value); |
273 addSource(Mem); | 274 addSource(Mem); |
274 } | 275 } |
275 | 276 |
276 InstX8632StoreQ::InstX8632StoreQ(Cfg *Func, Operand *Value, OperandX8632 *Mem) | 277 InstX8632StoreQ::InstX8632StoreQ(Cfg *Func, Variable *Value, |
| 278 OperandX8632Mem *Mem) |
277 : InstX8632(Func, InstX8632::StoreQ, 2, NULL) { | 279 : InstX8632(Func, InstX8632::StoreQ, 2, NULL) { |
278 addSource(Value); | 280 addSource(Value); |
279 addSource(Mem); | 281 addSource(Mem); |
280 } | 282 } |
281 | 283 |
282 InstX8632Movsx::InstX8632Movsx(Cfg *Func, Variable *Dest, Operand *Source) | 284 InstX8632Movsx::InstX8632Movsx(Cfg *Func, Variable *Dest, Operand *Source) |
283 : InstX8632(Func, InstX8632::Movsx, 1, Dest) { | 285 : InstX8632(Func, InstX8632::Movsx, 1, Dest) { |
284 addSource(Source); | 286 addSource(Source); |
285 } | 287 } |
286 | 288 |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 } else if (const ConstantInteger32 *Imm = | 531 } else if (const ConstantInteger32 *Imm = |
530 llvm::dyn_cast<ConstantInteger32>(Src)) { | 532 llvm::dyn_cast<ConstantInteger32>(Src)) { |
531 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); | 533 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); |
532 } else { | 534 } else { |
533 llvm_unreachable("Unexpected operand type"); | 535 llvm_unreachable("Unexpected operand type"); |
534 } | 536 } |
535 Ostream &Str = Func->getContext()->getStrEmit(); | 537 Ostream &Str = Func->getContext()->getStrEmit(); |
536 emitIASBytes(Str, Asm, StartPosition); | 538 emitIASBytes(Str, Asm, StartPosition); |
537 } | 539 } |
538 | 540 |
| 541 void emitIASAddrOpTyGPR(const Cfg *Func, Type Ty, const x86::Address &Addr, |
| 542 const Operand *Src, |
| 543 const x86::AssemblerX86::GPREmitterAddrOp &Emitter) { |
| 544 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 545 intptr_t StartPosition = Asm->GetPosition(); |
| 546 // Src can only be Reg or Immediate. |
| 547 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 548 assert(SrcVar->hasReg()); |
| 549 RegX8632::GPRRegister SrcReg = |
| 550 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); |
| 551 (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg); |
| 552 } else if (const ConstantInteger32 *Imm = |
| 553 llvm::dyn_cast<ConstantInteger32>(Src)) { |
| 554 (Asm->*(Emitter.AddrImm))(Ty, Addr, x86::Immediate(Imm->getValue())); |
| 555 } else { |
| 556 llvm_unreachable("Unexpected operand type"); |
| 557 } |
| 558 Ostream &Str = Func->getContext()->getStrEmit(); |
| 559 emitIASBytes(Str, Asm, StartPosition); |
| 560 } |
| 561 |
539 void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, | 562 void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, |
540 const Operand *Src, | 563 const Operand *Src, |
541 const x86::AssemblerX86::GPREmitterShiftOp &Emitter) { | 564 const x86::AssemblerX86::GPREmitterShiftOp &Emitter) { |
542 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 565 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
543 intptr_t StartPosition = Asm->GetPosition(); | 566 intptr_t StartPosition = Asm->GetPosition(); |
544 // Technically, the Dest Var can be mem as well, but we only use Reg. | 567 // Technically, the Dest Var can be mem as well, but we only use Reg. |
545 // We can extend this to check Dest if we decide to use that form. | 568 // We can extend this to check Dest if we decide to use that form. |
546 assert(Var->hasReg()); | 569 assert(Var->hasReg()); |
547 // We cheat a little and use GPRRegister even for byte operations. | 570 // We cheat a little and use GPRRegister even for byte operations. |
548 RegX8632::GPRRegister VarReg = | 571 RegX8632::GPRRegister VarReg = |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
588 } else if (const ConstantInteger32 *Imm = | 611 } else if (const ConstantInteger32 *Imm = |
589 llvm::dyn_cast<ConstantInteger32>(Src)) { | 612 llvm::dyn_cast<ConstantInteger32>(Src)) { |
590 (Asm->*(Emitter.XmmImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); | 613 (Asm->*(Emitter.XmmImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); |
591 } else { | 614 } else { |
592 llvm_unreachable("Unexpected operand type"); | 615 llvm_unreachable("Unexpected operand type"); |
593 } | 616 } |
594 Ostream &Str = Func->getContext()->getStrEmit(); | 617 Ostream &Str = Func->getContext()->getStrEmit(); |
595 emitIASBytes(Str, Asm, StartPosition); | 618 emitIASBytes(Str, Asm, StartPosition); |
596 } | 619 } |
597 | 620 |
598 void | 621 void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var, |
599 emitIASVarOperandTyXMM(const Cfg *Func, Type Ty, const Variable *Var, | |
600 const Operand *Src, | 622 const Operand *Src, |
601 const x86::AssemblerX86::XmmEmitterTwoOps &Emitter) { | 623 const x86::AssemblerX86::XmmEmitterRegOp &Emitter) { |
602 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 624 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
603 intptr_t StartPosition = Asm->GetPosition(); | 625 intptr_t StartPosition = Asm->GetPosition(); |
604 assert(Var->hasReg()); | 626 assert(Var->hasReg()); |
605 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); | 627 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); |
606 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { | 628 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
607 if (SrcVar->hasReg()) { | 629 if (SrcVar->hasReg()) { |
608 RegX8632::XmmRegister SrcReg = | 630 RegX8632::XmmRegister SrcReg = |
609 RegX8632::getEncodedXmm(SrcVar->getRegNum()); | 631 RegX8632::getEncodedXmm(SrcVar->getRegNum()); |
610 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); | 632 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); |
611 } else { | 633 } else { |
612 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) | 634 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) |
613 ->stackVarToAsmOperand(SrcVar); | 635 ->stackVarToAsmOperand(SrcVar); |
614 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); | 636 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); |
615 } | 637 } |
616 } else if (const OperandX8632Mem *Mem = | 638 } else if (const OperandX8632Mem *Mem = |
617 llvm::dyn_cast<OperandX8632Mem>(Src)) { | 639 llvm::dyn_cast<OperandX8632Mem>(Src)) { |
618 x86::Address SrcAddr = Mem->toAsmAddress(Asm); | 640 x86::Address SrcAddr = Mem->toAsmAddress(Asm); |
619 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcAddr); | 641 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcAddr); |
620 } else if (const Constant *Imm = llvm::dyn_cast<Constant>(Src)) { | 642 } else if (const Constant *Imm = llvm::dyn_cast<Constant>(Src)) { |
621 (Asm->*(Emitter.XmmAddr))( | 643 (Asm->*(Emitter.XmmAddr))( |
622 Ty, VarReg, x86::Address::ofConstPool(Func->getContext(), Asm, Imm)); | 644 Ty, VarReg, x86::Address::ofConstPool(Func->getContext(), Asm, Imm)); |
623 } else { | 645 } else { |
624 llvm_unreachable("Unexpected operand type"); | 646 llvm_unreachable("Unexpected operand type"); |
625 } | 647 } |
626 Ostream &Str = Func->getContext()->getStrEmit(); | 648 Ostream &Str = Func->getContext()->getStrEmit(); |
627 emitIASBytes(Str, Asm, StartPosition); | 649 emitIASBytes(Str, Asm, StartPosition); |
628 } | 650 } |
629 | 651 |
| 652 void emitIASMovlikeXMM(const Cfg *Func, const Variable *Dest, |
| 653 const Operand *Src, |
| 654 const x86::AssemblerX86::XmmEmitterMovOps Emitter) { |
| 655 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 656 intptr_t StartPosition = Asm->GetPosition(); |
| 657 if (Dest->hasReg()) { |
| 658 RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum()); |
| 659 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 660 if (SrcVar->hasReg()) { |
| 661 (Asm->*(Emitter.XmmXmm))(DestReg, |
| 662 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
| 663 } else { |
| 664 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 665 ->stackVarToAsmOperand(SrcVar)); |
| 666 (Asm->*(Emitter.XmmAddr))(DestReg, StackAddr); |
| 667 } |
| 668 } else if (const OperandX8632Mem *SrcMem = |
| 669 llvm::dyn_cast<OperandX8632Mem>(Src)) { |
| 670 (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm)); |
| 671 } else { |
| 672 llvm_unreachable("Unexpected operand type"); |
| 673 } |
| 674 } else { |
| 675 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 676 ->stackVarToAsmOperand(Dest)); |
| 677 // Src must be a register in this case. |
| 678 const Variable *SrcVar = llvm::cast<Variable>(Src); |
| 679 assert(SrcVar->hasReg()); |
| 680 (Asm->*(Emitter.AddrXmm))(StackAddr, |
| 681 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
| 682 } |
| 683 Ostream &Str = Func->getContext()->getStrEmit(); |
| 684 emitIASBytes(Str, Asm, StartPosition); |
| 685 } |
| 686 |
630 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source) { | 687 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source) { |
631 const Variable *Src = llvm::dyn_cast<const Variable>(Source); | 688 const Variable *Src = llvm::dyn_cast<const Variable>(Source); |
632 if (Src == NULL) | 689 if (Src == NULL) |
633 return false; | 690 return false; |
634 if (Dest->hasReg() && Dest->getRegNum() == Src->getRegNum()) { | 691 if (Dest->hasReg() && Dest->getRegNum() == Src->getRegNum()) { |
635 // TODO: On x86-64, instructions like "mov eax, eax" are used to | 692 // TODO: On x86-64, instructions like "mov eax, eax" are used to |
636 // clear the upper 32 bits of rax. We need to recognize and | 693 // clear the upper 32 bits of rax. We need to recognize and |
637 // preserve these. | 694 // preserve these. |
638 return true; | 695 return true; |
639 } | 696 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
685 template <> const char *InstX8632Idiv::Opcode = "idiv"; | 742 template <> const char *InstX8632Idiv::Opcode = "idiv"; |
686 template <> const char *InstX8632Divss::Opcode = "divss"; | 743 template <> const char *InstX8632Divss::Opcode = "divss"; |
687 template <> const char *InstX8632Rol::Opcode = "rol"; | 744 template <> const char *InstX8632Rol::Opcode = "rol"; |
688 template <> const char *InstX8632Shl::Opcode = "shl"; | 745 template <> const char *InstX8632Shl::Opcode = "shl"; |
689 template <> const char *InstX8632Psll::Opcode = "psll"; | 746 template <> const char *InstX8632Psll::Opcode = "psll"; |
690 template <> const char *InstX8632Shr::Opcode = "shr"; | 747 template <> const char *InstX8632Shr::Opcode = "shr"; |
691 template <> const char *InstX8632Sar::Opcode = "sar"; | 748 template <> const char *InstX8632Sar::Opcode = "sar"; |
692 template <> const char *InstX8632Psra::Opcode = "psra"; | 749 template <> const char *InstX8632Psra::Opcode = "psra"; |
693 template <> const char *InstX8632Pcmpeq::Opcode = "pcmpeq"; | 750 template <> const char *InstX8632Pcmpeq::Opcode = "pcmpeq"; |
694 template <> const char *InstX8632Pcmpgt::Opcode = "pcmpgt"; | 751 template <> const char *InstX8632Pcmpgt::Opcode = "pcmpgt"; |
695 template <> const char *InstX8632Movss::Opcode = "movss"; | 752 template <> const char *InstX8632MovssRegs::Opcode = "movss"; |
696 // Ternary ops | 753 // Ternary ops |
697 template <> const char *InstX8632Insertps::Opcode = "insertps"; | 754 template <> const char *InstX8632Insertps::Opcode = "insertps"; |
698 template <> const char *InstX8632Shufps::Opcode = "shufps"; | 755 template <> const char *InstX8632Shufps::Opcode = "shufps"; |
699 template <> const char *InstX8632Pinsr::Opcode = "pinsr"; | 756 template <> const char *InstX8632Pinsr::Opcode = "pinsr"; |
700 template <> const char *InstX8632Blendvps::Opcode = "blendvps"; | 757 template <> const char *InstX8632Blendvps::Opcode = "blendvps"; |
701 template <> const char *InstX8632Pblendvb::Opcode = "pblendvb"; | 758 template <> const char *InstX8632Pblendvb::Opcode = "pblendvb"; |
702 // Three address ops | 759 // Three address ops |
703 template <> const char *InstX8632Pextr::Opcode = "pextr"; | 760 template <> const char *InstX8632Pextr::Opcode = "pextr"; |
704 template <> const char *InstX8632Pshufd::Opcode = "pshufd"; | 761 template <> const char *InstX8632Pshufd::Opcode = "pshufd"; |
705 | 762 |
(...skipping 11 matching lines...) Expand all Loading... |
717 &x86::AssemblerX86::bsf, &x86::AssemblerX86::bsf, NULL}; | 774 &x86::AssemblerX86::bsf, &x86::AssemblerX86::bsf, NULL}; |
718 template <> | 775 template <> |
719 const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsr::Emitter = { | 776 const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsr::Emitter = { |
720 &x86::AssemblerX86::bsr, &x86::AssemblerX86::bsr, NULL}; | 777 &x86::AssemblerX86::bsr, &x86::AssemblerX86::bsr, NULL}; |
721 template <> | 778 template <> |
722 const x86::AssemblerX86::GPREmitterRegOp InstX8632Lea::Emitter = { | 779 const x86::AssemblerX86::GPREmitterRegOp InstX8632Lea::Emitter = { |
723 /* reg/reg and reg/imm are illegal */ NULL, &x86::AssemblerX86::lea, NULL}; | 780 /* reg/reg and reg/imm are illegal */ NULL, &x86::AssemblerX86::lea, NULL}; |
724 | 781 |
725 // Unary XMM ops | 782 // Unary XMM ops |
726 template <> | 783 template <> |
727 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Sqrtss::Emitter = { | 784 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Sqrtss::Emitter = { |
728 &x86::AssemblerX86::sqrtss, &x86::AssemblerX86::sqrtss, NULL}; | 785 &x86::AssemblerX86::sqrtss, &x86::AssemblerX86::sqrtss}; |
729 | 786 |
730 // Binary GPR ops | 787 // Binary GPR ops |
731 template <> | 788 template <> |
732 const x86::AssemblerX86::GPREmitterRegOp InstX8632Add::Emitter = { | 789 const x86::AssemblerX86::GPREmitterRegOp InstX8632Add::Emitter = { |
733 &x86::AssemblerX86::add, &x86::AssemblerX86::add, &x86::AssemblerX86::add}; | 790 &x86::AssemblerX86::add, &x86::AssemblerX86::add, &x86::AssemblerX86::add}; |
734 template <> | 791 template <> |
735 const x86::AssemblerX86::GPREmitterRegOp InstX8632Adc::Emitter = { | 792 const x86::AssemblerX86::GPREmitterRegOp InstX8632Adc::Emitter = { |
736 &x86::AssemblerX86::adc, &x86::AssemblerX86::adc, &x86::AssemblerX86::adc}; | 793 &x86::AssemblerX86::adc, &x86::AssemblerX86::adc, &x86::AssemblerX86::adc}; |
737 template <> | 794 template <> |
738 const x86::AssemblerX86::GPREmitterRegOp InstX8632And::Emitter = { | 795 const x86::AssemblerX86::GPREmitterRegOp InstX8632And::Emitter = { |
(...skipping 20 matching lines...) Expand all Loading... |
759 &x86::AssemblerX86::sar, &x86::AssemblerX86::sar}; | 816 &x86::AssemblerX86::sar, &x86::AssemblerX86::sar}; |
760 template <> | 817 template <> |
761 const x86::AssemblerX86::GPREmitterShiftOp InstX8632Shl::Emitter = { | 818 const x86::AssemblerX86::GPREmitterShiftOp InstX8632Shl::Emitter = { |
762 &x86::AssemblerX86::shl, &x86::AssemblerX86::shl}; | 819 &x86::AssemblerX86::shl, &x86::AssemblerX86::shl}; |
763 template <> | 820 template <> |
764 const x86::AssemblerX86::GPREmitterShiftOp InstX8632Shr::Emitter = { | 821 const x86::AssemblerX86::GPREmitterShiftOp InstX8632Shr::Emitter = { |
765 &x86::AssemblerX86::shr, &x86::AssemblerX86::shr}; | 822 &x86::AssemblerX86::shr, &x86::AssemblerX86::shr}; |
766 | 823 |
767 // Binary XMM ops | 824 // Binary XMM ops |
768 template <> | 825 template <> |
769 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Addss::Emitter = { | 826 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Addss::Emitter = { |
770 &x86::AssemblerX86::addss, &x86::AssemblerX86::addss, NULL}; | 827 &x86::AssemblerX86::addss, &x86::AssemblerX86::addss}; |
771 template <> | 828 template <> |
772 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Addps::Emitter = { | 829 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Addps::Emitter = { |
773 &x86::AssemblerX86::addps, &x86::AssemblerX86::addps, NULL}; | 830 &x86::AssemblerX86::addps, &x86::AssemblerX86::addps}; |
774 template <> | 831 template <> |
775 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Divss::Emitter = { | 832 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Divss::Emitter = { |
776 &x86::AssemblerX86::divss, &x86::AssemblerX86::divss, NULL}; | 833 &x86::AssemblerX86::divss, &x86::AssemblerX86::divss}; |
777 template <> | 834 template <> |
778 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Divps::Emitter = { | 835 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Divps::Emitter = { |
779 &x86::AssemblerX86::divps, &x86::AssemblerX86::divps, NULL}; | 836 &x86::AssemblerX86::divps, &x86::AssemblerX86::divps}; |
780 template <> | 837 template <> |
781 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Mulss::Emitter = { | 838 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Mulss::Emitter = { |
782 &x86::AssemblerX86::mulss, &x86::AssemblerX86::mulss, NULL}; | 839 &x86::AssemblerX86::mulss, &x86::AssemblerX86::mulss}; |
783 template <> | 840 template <> |
784 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Mulps::Emitter = { | 841 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Mulps::Emitter = { |
785 &x86::AssemblerX86::mulps, &x86::AssemblerX86::mulps, NULL}; | 842 &x86::AssemblerX86::mulps, &x86::AssemblerX86::mulps}; |
786 template <> | 843 template <> |
787 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Padd::Emitter = { | 844 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Padd::Emitter = { |
788 &x86::AssemblerX86::padd, &x86::AssemblerX86::padd, NULL}; | 845 &x86::AssemblerX86::padd, &x86::AssemblerX86::padd}; |
789 template <> | 846 template <> |
790 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pand::Emitter = { | 847 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pand::Emitter = { |
791 &x86::AssemblerX86::pand, &x86::AssemblerX86::pand, NULL}; | 848 &x86::AssemblerX86::pand, &x86::AssemblerX86::pand}; |
792 template <> | 849 template <> |
793 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pandn::Emitter = { | 850 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pandn::Emitter = { |
794 &x86::AssemblerX86::pandn, &x86::AssemblerX86::pandn, NULL}; | 851 &x86::AssemblerX86::pandn, &x86::AssemblerX86::pandn}; |
795 template <> | 852 template <> |
796 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pcmpeq::Emitter = { | 853 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pcmpeq::Emitter = { |
797 &x86::AssemblerX86::pcmpeq, &x86::AssemblerX86::pcmpeq, NULL}; | 854 &x86::AssemblerX86::pcmpeq, &x86::AssemblerX86::pcmpeq}; |
798 template <> | 855 template <> |
799 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pcmpgt::Emitter = { | 856 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pcmpgt::Emitter = { |
800 &x86::AssemblerX86::pcmpgt, &x86::AssemblerX86::pcmpgt, NULL}; | 857 &x86::AssemblerX86::pcmpgt, &x86::AssemblerX86::pcmpgt}; |
801 template <> | 858 template <> |
802 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pmull::Emitter = { | 859 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pmull::Emitter = { |
803 &x86::AssemblerX86::pmull, &x86::AssemblerX86::pmull, NULL}; | 860 &x86::AssemblerX86::pmull, &x86::AssemblerX86::pmull}; |
804 template <> | 861 template <> |
805 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pmuludq::Emitter = { | 862 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pmuludq::Emitter = { |
806 &x86::AssemblerX86::pmuludq, &x86::AssemblerX86::pmuludq, NULL}; | 863 &x86::AssemblerX86::pmuludq, &x86::AssemblerX86::pmuludq}; |
807 template <> | 864 template <> |
808 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Por::Emitter = { | 865 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Por::Emitter = { |
809 &x86::AssemblerX86::por, &x86::AssemblerX86::por, NULL}; | 866 &x86::AssemblerX86::por, &x86::AssemblerX86::por}; |
810 template <> | 867 template <> |
811 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Psub::Emitter = { | 868 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Psub::Emitter = { |
812 &x86::AssemblerX86::psub, &x86::AssemblerX86::psub, NULL}; | 869 &x86::AssemblerX86::psub, &x86::AssemblerX86::psub}; |
813 template <> | 870 template <> |
814 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pxor::Emitter = { | 871 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pxor::Emitter = { |
815 &x86::AssemblerX86::pxor, &x86::AssemblerX86::pxor, NULL}; | 872 &x86::AssemblerX86::pxor, &x86::AssemblerX86::pxor}; |
816 template <> | 873 template <> |
817 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Subss::Emitter = { | 874 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Subss::Emitter = { |
818 &x86::AssemblerX86::subss, &x86::AssemblerX86::subss, NULL}; | 875 &x86::AssemblerX86::subss, &x86::AssemblerX86::subss}; |
819 template <> | 876 template <> |
820 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Subps::Emitter = { | 877 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Subps::Emitter = { |
821 &x86::AssemblerX86::subps, &x86::AssemblerX86::subps, NULL}; | 878 &x86::AssemblerX86::subps, &x86::AssemblerX86::subps}; |
822 | 879 |
823 // Binary XMM Shift ops | 880 // Binary XMM Shift ops |
824 template <> | 881 template <> |
825 const x86::AssemblerX86::XmmEmitterShiftOp InstX8632Psll::Emitter = { | 882 const x86::AssemblerX86::XmmEmitterShiftOp InstX8632Psll::Emitter = { |
826 &x86::AssemblerX86::psll, &x86::AssemblerX86::psll, | 883 &x86::AssemblerX86::psll, &x86::AssemblerX86::psll, |
827 &x86::AssemblerX86::psll}; | 884 &x86::AssemblerX86::psll}; |
828 template <> | 885 template <> |
829 const x86::AssemblerX86::XmmEmitterShiftOp InstX8632Psra::Emitter = { | 886 const x86::AssemblerX86::XmmEmitterShiftOp InstX8632Psra::Emitter = { |
830 &x86::AssemblerX86::psra, &x86::AssemblerX86::psra, | 887 &x86::AssemblerX86::psra, &x86::AssemblerX86::psra, |
831 &x86::AssemblerX86::psra}; | 888 &x86::AssemblerX86::psra}; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
879 bool InstructionSetIsValid = | 936 bool InstructionSetIsValid = |
880 Ty == IceType_v8i16 || | 937 Ty == IceType_v8i16 || |
881 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 938 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
882 TargetX8632::SSE4_1; | 939 TargetX8632::SSE4_1; |
883 (void)TypesAreValid; | 940 (void)TypesAreValid; |
884 (void)InstructionSetIsValid; | 941 (void)InstructionSetIsValid; |
885 assert(TypesAreValid); | 942 assert(TypesAreValid); |
886 assert(InstructionSetIsValid); | 943 assert(InstructionSetIsValid); |
887 assert(getSrcSize() == 2); | 944 assert(getSrcSize() == 2); |
888 Type ElementTy = typeElementType(Ty); | 945 Type ElementTy = typeElementType(Ty); |
889 emitIASVarOperandTyXMM(Func, ElementTy, getDest(), getSrc(1), Emitter); | 946 emitIASRegOpTyXMM(Func, ElementTy, getDest(), getSrc(1), Emitter); |
890 } | 947 } |
891 | 948 |
892 template <> void InstX8632Subss::emit(const Cfg *Func) const { | 949 template <> void InstX8632Subss::emit(const Cfg *Func) const { |
893 char buf[30]; | 950 char buf[30]; |
894 snprintf(buf, llvm::array_lengthof(buf), "sub%s", | 951 snprintf(buf, llvm::array_lengthof(buf), "sub%s", |
895 TypeX8632Attributes[getDest()->getType()].SdSsString); | 952 TypeX8632Attributes[getDest()->getType()].SdSsString); |
896 emitTwoAddress(buf, this, Func); | 953 emitTwoAddress(buf, this, Func); |
897 } | 954 } |
898 | 955 |
899 template <> void InstX8632Psub::emit(const Cfg *Func) const { | 956 template <> void InstX8632Psub::emit(const Cfg *Func) const { |
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1357 void InstX8632Icmp::emit(const Cfg *Func) const { | 1414 void InstX8632Icmp::emit(const Cfg *Func) const { |
1358 Ostream &Str = Func->getContext()->getStrEmit(); | 1415 Ostream &Str = Func->getContext()->getStrEmit(); |
1359 assert(getSrcSize() == 2); | 1416 assert(getSrcSize() == 2); |
1360 Str << "\tcmp\t"; | 1417 Str << "\tcmp\t"; |
1361 getSrc(0)->emit(Func); | 1418 getSrc(0)->emit(Func); |
1362 Str << ", "; | 1419 Str << ", "; |
1363 getSrc(1)->emit(Func); | 1420 getSrc(1)->emit(Func); |
1364 Str << "\n"; | 1421 Str << "\n"; |
1365 } | 1422 } |
1366 | 1423 |
| 1424 void InstX8632Icmp::emitIAS(const Cfg *Func) const { |
| 1425 assert(getSrcSize() == 2); |
| 1426 const Operand *Src0 = getSrc(0); |
| 1427 const Operand *Src1 = getSrc(1); |
| 1428 Type Ty = Src0->getType(); |
| 1429 static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = { |
| 1430 &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp, |
| 1431 &x86::AssemblerX86::cmp}; |
| 1432 static const x86::AssemblerX86::GPREmitterAddrOp AddrEmitter = { |
| 1433 &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp}; |
| 1434 if (const Variable *SrcVar0 = llvm::dyn_cast<Variable>(Src0)) { |
| 1435 if (SrcVar0->hasReg()) { |
| 1436 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); |
| 1437 } else { |
| 1438 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 1439 ->stackVarToAsmOperand(SrcVar0)); |
| 1440 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Src1, AddrEmitter); |
| 1441 } |
| 1442 } else if (const OperandX8632Mem *SrcMem0 = |
| 1443 llvm::dyn_cast<OperandX8632Mem>(Src0)) { |
| 1444 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1445 emitIASAddrOpTyGPR(Func, Ty, SrcMem0->toAsmAddress(Asm), Src1, AddrEmitter); |
| 1446 } |
| 1447 } |
| 1448 |
1367 void InstX8632Icmp::dump(const Cfg *Func) const { | 1449 void InstX8632Icmp::dump(const Cfg *Func) const { |
1368 Ostream &Str = Func->getContext()->getStrDump(); | 1450 Ostream &Str = Func->getContext()->getStrDump(); |
1369 Str << "cmp." << getSrc(0)->getType() << " "; | 1451 Str << "cmp." << getSrc(0)->getType() << " "; |
1370 dumpSources(Func); | 1452 dumpSources(Func); |
1371 } | 1453 } |
1372 | 1454 |
1373 void InstX8632Ucomiss::emit(const Cfg *Func) const { | 1455 void InstX8632Ucomiss::emit(const Cfg *Func) const { |
1374 Ostream &Str = Func->getContext()->getStrEmit(); | 1456 Ostream &Str = Func->getContext()->getStrEmit(); |
1375 assert(getSrcSize() == 2); | 1457 assert(getSrcSize() == 2); |
1376 Str << "\tucomi" << TypeX8632Attributes[getSrc(0)->getType()].SdSsString | 1458 Str << "\tucomi" << TypeX8632Attributes[getSrc(0)->getType()].SdSsString |
1377 << "\t"; | 1459 << "\t"; |
1378 getSrc(0)->emit(Func); | 1460 getSrc(0)->emit(Func); |
1379 Str << ", "; | 1461 Str << ", "; |
1380 getSrc(1)->emit(Func); | 1462 getSrc(1)->emit(Func); |
1381 Str << "\n"; | 1463 Str << "\n"; |
1382 } | 1464 } |
1383 | 1465 |
1384 void InstX8632Ucomiss::emitIAS(const Cfg *Func) const { | 1466 void InstX8632Ucomiss::emitIAS(const Cfg *Func) const { |
1385 assert(getSrcSize() == 2); | 1467 assert(getSrcSize() == 2); |
1386 // Currently src0 is always a variable by convention, to avoid having | 1468 // Currently src0 is always a variable by convention, to avoid having |
1387 // two memory operands. | 1469 // two memory operands. |
1388 assert(llvm::isa<Variable>(getSrc(0))); | 1470 assert(llvm::isa<Variable>(getSrc(0))); |
1389 const Variable *Src0 = llvm::cast<Variable>(getSrc(0)); | 1471 const Variable *Src0 = llvm::cast<Variable>(getSrc(0)); |
1390 Type Ty = Src0->getType(); | 1472 Type Ty = Src0->getType(); |
1391 const static x86::AssemblerX86::XmmEmitterTwoOps Emitter = { | 1473 const static x86::AssemblerX86::XmmEmitterRegOp Emitter = { |
1392 &x86::AssemblerX86::ucomiss, &x86::AssemblerX86::ucomiss, NULL}; | 1474 &x86::AssemblerX86::ucomiss, &x86::AssemblerX86::ucomiss}; |
1393 emitIASVarOperandTyXMM(Func, Ty, Src0, getSrc(1), Emitter); | 1475 emitIASRegOpTyXMM(Func, Ty, Src0, getSrc(1), Emitter); |
1394 } | 1476 } |
1395 | 1477 |
1396 void InstX8632Ucomiss::dump(const Cfg *Func) const { | 1478 void InstX8632Ucomiss::dump(const Cfg *Func) const { |
1397 Ostream &Str = Func->getContext()->getStrDump(); | 1479 Ostream &Str = Func->getContext()->getStrDump(); |
1398 Str << "ucomiss." << getSrc(0)->getType() << " "; | 1480 Str << "ucomiss." << getSrc(0)->getType() << " "; |
1399 dumpSources(Func); | 1481 dumpSources(Func); |
1400 } | 1482 } |
1401 | 1483 |
1402 void InstX8632UD2::emit(const Cfg *Func) const { | 1484 void InstX8632UD2::emit(const Cfg *Func) const { |
1403 Ostream &Str = Func->getContext()->getStrEmit(); | 1485 Ostream &Str = Func->getContext()->getStrEmit(); |
1404 assert(getSrcSize() == 0); | 1486 assert(getSrcSize() == 0); |
1405 Str << "\tud2\n"; | 1487 Str << "\tud2\n"; |
1406 } | 1488 } |
1407 | 1489 |
| 1490 void InstX8632UD2::emitIAS(const Cfg *Func) const { |
| 1491 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1492 intptr_t StartPosition = Asm->GetPosition(); |
| 1493 Asm->ud2(); |
| 1494 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1495 emitIASBytes(Str, Asm, StartPosition); |
| 1496 } |
| 1497 |
1408 void InstX8632UD2::dump(const Cfg *Func) const { | 1498 void InstX8632UD2::dump(const Cfg *Func) const { |
1409 Ostream &Str = Func->getContext()->getStrDump(); | 1499 Ostream &Str = Func->getContext()->getStrDump(); |
1410 Str << "ud2\n"; | 1500 Str << "ud2\n"; |
1411 } | 1501 } |
1412 | 1502 |
1413 void InstX8632Test::emit(const Cfg *Func) const { | 1503 void InstX8632Test::emit(const Cfg *Func) const { |
1414 Ostream &Str = Func->getContext()->getStrEmit(); | 1504 Ostream &Str = Func->getContext()->getStrEmit(); |
1415 assert(getSrcSize() == 2); | 1505 assert(getSrcSize() == 2); |
1416 Str << "\ttest\t"; | 1506 Str << "\ttest\t"; |
1417 getSrc(0)->emit(Func); | 1507 getSrc(0)->emit(Func); |
1418 Str << ", "; | 1508 Str << ", "; |
1419 getSrc(1)->emit(Func); | 1509 getSrc(1)->emit(Func); |
1420 Str << "\n"; | 1510 Str << "\n"; |
1421 } | 1511 } |
1422 | 1512 |
| 1513 void InstX8632Test::emitIAS(const Cfg *Func) const { |
| 1514 assert(getSrcSize() == 2); |
| 1515 const Operand *Src0 = getSrc(0); |
| 1516 const Operand *Src1 = getSrc(1); |
| 1517 Type Ty = Src0->getType(); |
| 1518 // The Reg/Addr form of test is not encodeable. |
| 1519 static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = { |
| 1520 &x86::AssemblerX86::test, NULL, &x86::AssemblerX86::test}; |
| 1521 static const x86::AssemblerX86::GPREmitterAddrOp AddrEmitter = { |
| 1522 &x86::AssemblerX86::test, &x86::AssemblerX86::test}; |
| 1523 if (const Variable *SrcVar0 = llvm::dyn_cast<Variable>(Src0)) { |
| 1524 if (SrcVar0->hasReg()) { |
| 1525 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); |
| 1526 } else { |
| 1527 llvm_unreachable("Nothing actually generates this so it's untested"); |
| 1528 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 1529 ->stackVarToAsmOperand(SrcVar0)); |
| 1530 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Src1, AddrEmitter); |
| 1531 } |
| 1532 } else if (const OperandX8632Mem *SrcMem0 = |
| 1533 llvm::dyn_cast<OperandX8632Mem>(Src0)) { |
| 1534 llvm_unreachable("Nothing actually generates this so it's untested"); |
| 1535 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1536 emitIASAddrOpTyGPR(Func, Ty, SrcMem0->toAsmAddress(Asm), Src1, AddrEmitter); |
| 1537 } |
| 1538 } |
| 1539 |
1423 void InstX8632Test::dump(const Cfg *Func) const { | 1540 void InstX8632Test::dump(const Cfg *Func) const { |
1424 Ostream &Str = Func->getContext()->getStrDump(); | 1541 Ostream &Str = Func->getContext()->getStrDump(); |
1425 Str << "test." << getSrc(0)->getType() << " "; | 1542 Str << "test." << getSrc(0)->getType() << " "; |
1426 dumpSources(Func); | 1543 dumpSources(Func); |
1427 } | 1544 } |
1428 | 1545 |
1429 void InstX8632Mfence::emit(const Cfg *Func) const { | 1546 void InstX8632Mfence::emit(const Cfg *Func) const { |
1430 Ostream &Str = Func->getContext()->getStrEmit(); | 1547 Ostream &Str = Func->getContext()->getStrEmit(); |
1431 assert(getSrcSize() == 0); | 1548 assert(getSrcSize() == 0); |
1432 Str << "\tmfence\n"; | 1549 Str << "\tmfence\n"; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1467 void InstX8632StoreP::emit(const Cfg *Func) const { | 1584 void InstX8632StoreP::emit(const Cfg *Func) const { |
1468 Ostream &Str = Func->getContext()->getStrEmit(); | 1585 Ostream &Str = Func->getContext()->getStrEmit(); |
1469 assert(getSrcSize() == 2); | 1586 assert(getSrcSize() == 2); |
1470 Str << "\tmovups\t"; | 1587 Str << "\tmovups\t"; |
1471 getSrc(1)->emit(Func); | 1588 getSrc(1)->emit(Func); |
1472 Str << ", "; | 1589 Str << ", "; |
1473 getSrc(0)->emit(Func); | 1590 getSrc(0)->emit(Func); |
1474 Str << "\n"; | 1591 Str << "\n"; |
1475 } | 1592 } |
1476 | 1593 |
| 1594 void InstX8632StoreP::emitIAS(const Cfg *Func) const { |
| 1595 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1596 intptr_t StartPosition = Asm->GetPosition(); |
| 1597 assert(getSrcSize() == 2); |
| 1598 const Variable *Src = llvm::cast<Variable>(getSrc(0)); |
| 1599 const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); |
| 1600 assert(Src->hasReg()); |
| 1601 Asm->movups(DestMem->toAsmAddress(Asm), |
| 1602 RegX8632::getEncodedXmm(Src->getRegNum())); |
| 1603 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1604 emitIASBytes(Str, Asm, StartPosition); |
| 1605 } |
| 1606 |
1477 void InstX8632StoreP::dump(const Cfg *Func) const { | 1607 void InstX8632StoreP::dump(const Cfg *Func) const { |
1478 Ostream &Str = Func->getContext()->getStrDump(); | 1608 Ostream &Str = Func->getContext()->getStrDump(); |
1479 Str << "storep." << getSrc(0)->getType() << " "; | 1609 Str << "storep." << getSrc(0)->getType() << " "; |
1480 getSrc(1)->dump(Func); | 1610 getSrc(1)->dump(Func); |
1481 Str << ", "; | 1611 Str << ", "; |
1482 getSrc(0)->dump(Func); | 1612 getSrc(0)->dump(Func); |
1483 } | 1613 } |
1484 | 1614 |
1485 void InstX8632StoreQ::emit(const Cfg *Func) const { | 1615 void InstX8632StoreQ::emit(const Cfg *Func) const { |
1486 Ostream &Str = Func->getContext()->getStrEmit(); | 1616 Ostream &Str = Func->getContext()->getStrEmit(); |
1487 assert(getSrcSize() == 2); | 1617 assert(getSrcSize() == 2); |
1488 assert(getSrc(1)->getType() == IceType_i64 || | 1618 assert(getSrc(1)->getType() == IceType_i64 || |
1489 getSrc(1)->getType() == IceType_f64); | 1619 getSrc(1)->getType() == IceType_f64); |
1490 Str << "\tmovq\t"; | 1620 Str << "\tmovq\t"; |
1491 getSrc(1)->emit(Func); | 1621 getSrc(1)->emit(Func); |
1492 Str << ", "; | 1622 Str << ", "; |
1493 getSrc(0)->emit(Func); | 1623 getSrc(0)->emit(Func); |
1494 Str << "\n"; | 1624 Str << "\n"; |
1495 } | 1625 } |
1496 | 1626 |
| 1627 void InstX8632StoreQ::emitIAS(const Cfg *Func) const { |
| 1628 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1629 intptr_t StartPosition = Asm->GetPosition(); |
| 1630 assert(getSrcSize() == 2); |
| 1631 const Variable *Src = llvm::cast<Variable>(getSrc(0)); |
| 1632 const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); |
| 1633 assert(Src->hasReg()); |
| 1634 Asm->movq(DestMem->toAsmAddress(Asm), |
| 1635 RegX8632::getEncodedXmm(Src->getRegNum())); |
| 1636 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1637 emitIASBytes(Str, Asm, StartPosition); |
| 1638 } |
| 1639 |
1497 void InstX8632StoreQ::dump(const Cfg *Func) const { | 1640 void InstX8632StoreQ::dump(const Cfg *Func) const { |
1498 Ostream &Str = Func->getContext()->getStrDump(); | 1641 Ostream &Str = Func->getContext()->getStrDump(); |
1499 Str << "storeq." << getSrc(0)->getType() << " "; | 1642 Str << "storeq." << getSrc(0)->getType() << " "; |
1500 getSrc(1)->dump(Func); | 1643 getSrc(1)->dump(Func); |
1501 Str << ", "; | 1644 Str << ", "; |
1502 getSrc(0)->dump(Func); | 1645 getSrc(0)->dump(Func); |
1503 } | 1646 } |
1504 | 1647 |
1505 template <> void InstX8632Lea::emit(const Cfg *Func) const { | 1648 template <> void InstX8632Lea::emit(const Cfg *Func) const { |
1506 Ostream &Str = Func->getContext()->getStrEmit(); | 1649 Ostream &Str = Func->getContext()->getStrEmit(); |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1614 // operands. | 1757 // operands. |
1615 Ostream &Str = Func->getContext()->getStrEmit(); | 1758 Ostream &Str = Func->getContext()->getStrEmit(); |
1616 assert(getSrcSize() == 1); | 1759 assert(getSrcSize() == 1); |
1617 Str << "\tmovups\t"; | 1760 Str << "\tmovups\t"; |
1618 getDest()->emit(Func); | 1761 getDest()->emit(Func); |
1619 Str << ", "; | 1762 Str << ", "; |
1620 getSrc(0)->emit(Func); | 1763 getSrc(0)->emit(Func); |
1621 Str << "\n"; | 1764 Str << "\n"; |
1622 } | 1765 } |
1623 | 1766 |
| 1767 template <> void InstX8632Movp::emitIAS(const Cfg *Func) const { |
| 1768 assert(getSrcSize() == 1); |
| 1769 assert(isVectorType(getDest()->getType())); |
| 1770 const Variable *Dest = getDest(); |
| 1771 const Operand *Src = getSrc(0); |
| 1772 const static x86::AssemblerX86::XmmEmitterMovOps Emitter = { |
| 1773 &x86::AssemblerX86::movups, &x86::AssemblerX86::movups, |
| 1774 &x86::AssemblerX86::movups}; |
| 1775 emitIASMovlikeXMM(Func, Dest, Src, Emitter); |
| 1776 } |
| 1777 |
1624 template <> void InstX8632Movq::emit(const Cfg *Func) const { | 1778 template <> void InstX8632Movq::emit(const Cfg *Func) const { |
1625 Ostream &Str = Func->getContext()->getStrEmit(); | 1779 Ostream &Str = Func->getContext()->getStrEmit(); |
1626 assert(getSrcSize() == 1); | 1780 assert(getSrcSize() == 1); |
1627 assert(getDest()->getType() == IceType_i64 || | 1781 assert(getDest()->getType() == IceType_i64 || |
1628 getDest()->getType() == IceType_f64); | 1782 getDest()->getType() == IceType_f64); |
1629 Str << "\tmovq\t"; | 1783 Str << "\tmovq\t"; |
1630 getDest()->emit(Func); | 1784 getDest()->emit(Func); |
1631 Str << ", "; | 1785 Str << ", "; |
1632 getSrc(0)->emit(Func); | 1786 getSrc(0)->emit(Func); |
1633 Str << "\n"; | 1787 Str << "\n"; |
1634 } | 1788 } |
1635 | 1789 |
| 1790 template <> void InstX8632Movq::emitIAS(const Cfg *Func) const { |
| 1791 assert(getSrcSize() == 1); |
| 1792 assert(getDest()->getType() == IceType_i64 || |
| 1793 getDest()->getType() == IceType_f64); |
| 1794 const Variable *Dest = getDest(); |
| 1795 const Operand *Src = getSrc(0); |
| 1796 const static x86::AssemblerX86::XmmEmitterMovOps Emitter = { |
| 1797 &x86::AssemblerX86::movq, &x86::AssemblerX86::movq, |
| 1798 &x86::AssemblerX86::movq}; |
| 1799 emitIASMovlikeXMM(Func, Dest, Src, Emitter); |
| 1800 } |
| 1801 |
| 1802 template <> void InstX8632MovssRegs::emitIAS(const Cfg *Func) const { |
| 1803 // This is Binop variant is only intended to be used for reg-reg moves |
| 1804 // where part of the Dest register is untouched. |
| 1805 assert(getSrcSize() == 2); |
| 1806 const Variable *Dest = getDest(); |
| 1807 assert(Dest == getSrc(0)); |
| 1808 const Variable *Src = llvm::cast<Variable>(getSrc(1)); |
| 1809 assert(Dest->hasReg() && Src->hasReg()); |
| 1810 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1811 intptr_t StartPosition = Asm->GetPosition(); |
| 1812 Asm->movss(RegX8632::getEncodedXmm(Dest->getRegNum()), |
| 1813 RegX8632::getEncodedXmm(Src->getRegNum())); |
| 1814 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1815 emitIASBytes(Str, Asm, StartPosition); |
| 1816 } |
| 1817 |
1636 void InstX8632Movsx::emit(const Cfg *Func) const { | 1818 void InstX8632Movsx::emit(const Cfg *Func) const { |
1637 Ostream &Str = Func->getContext()->getStrEmit(); | 1819 Ostream &Str = Func->getContext()->getStrEmit(); |
1638 assert(getSrcSize() == 1); | 1820 assert(getSrcSize() == 1); |
1639 Str << "\tmovsx\t"; | 1821 Str << "\tmovsx\t"; |
1640 getDest()->emit(Func); | 1822 getDest()->emit(Func); |
1641 Str << ", "; | 1823 Str << ", "; |
1642 getSrc(0)->emit(Func); | 1824 getSrc(0)->emit(Func); |
1643 Str << "\n"; | 1825 Str << "\n"; |
1644 } | 1826 } |
1645 | 1827 |
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2184 } | 2366 } |
2185 Str << "("; | 2367 Str << "("; |
2186 if (Func) | 2368 if (Func) |
2187 Var->dump(Func); | 2369 Var->dump(Func); |
2188 else | 2370 else |
2189 Var->dump(Str); | 2371 Var->dump(Str); |
2190 Str << ")"; | 2372 Str << ")"; |
2191 } | 2373 } |
2192 | 2374 |
2193 } // end of namespace Ice | 2375 } // end of namespace Ice |
OLD | NEW |