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 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 } else if (const ConstantInteger32 *Imm = | 529 } else if (const ConstantInteger32 *Imm = |
530 llvm::dyn_cast<ConstantInteger32>(Src)) { | 530 llvm::dyn_cast<ConstantInteger32>(Src)) { |
531 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); | 531 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); |
532 } else { | 532 } else { |
533 llvm_unreachable("Unexpected operand type"); | 533 llvm_unreachable("Unexpected operand type"); |
534 } | 534 } |
535 Ostream &Str = Func->getContext()->getStrEmit(); | 535 Ostream &Str = Func->getContext()->getStrEmit(); |
536 emitIASBytes(Str, Asm, StartPosition); | 536 emitIASBytes(Str, Asm, StartPosition); |
537 } | 537 } |
538 | 538 |
| 539 void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, |
| 540 const Operand *Src, |
| 541 const x86::AssemblerX86::GPREmitterShiftOp &Emitter) { |
| 542 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 543 intptr_t StartPosition = Asm->GetPosition(); |
| 544 // 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. |
| 546 assert(Var->hasReg()); |
| 547 // We cheat a little and use GPRRegister even for byte operations. |
| 548 RegX8632::GPRRegister VarReg = |
| 549 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()); |
| 550 // Src must be reg == ECX or an Imm8. |
| 551 // This is asserted by the assembler. |
| 552 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 553 assert(SrcVar->hasReg()); |
| 554 RegX8632::GPRRegister SrcReg = |
| 555 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); |
| 556 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg); |
| 557 } else if (const ConstantInteger32 *Imm = |
| 558 llvm::dyn_cast<ConstantInteger32>(Src)) { |
| 559 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); |
| 560 } else { |
| 561 llvm_unreachable("Unexpected operand type"); |
| 562 } |
| 563 Ostream &Str = Func->getContext()->getStrEmit(); |
| 564 emitIASBytes(Str, Asm, StartPosition); |
| 565 } |
| 566 |
| 567 void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var, |
| 568 const Operand *Src, |
| 569 const x86::AssemblerX86::XmmEmitterShiftOp &Emitter) { |
| 570 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 571 intptr_t StartPosition = Asm->GetPosition(); |
| 572 assert(Var->hasReg()); |
| 573 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); |
| 574 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 575 if (SrcVar->hasReg()) { |
| 576 RegX8632::XmmRegister SrcReg = |
| 577 RegX8632::getEncodedXmm(SrcVar->getRegNum()); |
| 578 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); |
| 579 } else { |
| 580 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) |
| 581 ->stackVarToAsmOperand(SrcVar); |
| 582 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); |
| 583 } |
| 584 } else if (const OperandX8632Mem *Mem = |
| 585 llvm::dyn_cast<OperandX8632Mem>(Src)) { |
| 586 x86::Address SrcAddr = Mem->toAsmAddress(Asm); |
| 587 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcAddr); |
| 588 } else if (const ConstantInteger32 *Imm = |
| 589 llvm::dyn_cast<ConstantInteger32>(Src)) { |
| 590 (Asm->*(Emitter.XmmImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); |
| 591 } else { |
| 592 llvm_unreachable("Unexpected operand type"); |
| 593 } |
| 594 Ostream &Str = Func->getContext()->getStrEmit(); |
| 595 emitIASBytes(Str, Asm, StartPosition); |
| 596 } |
| 597 |
539 void | 598 void |
540 emitIASVarOperandTyXMM(const Cfg *Func, Type Ty, const Variable *Var, | 599 emitIASVarOperandTyXMM(const Cfg *Func, Type Ty, const Variable *Var, |
541 const Operand *Src, | 600 const Operand *Src, |
542 const x86::AssemblerX86::XmmEmitterTwoOps &Emitter) { | 601 const x86::AssemblerX86::XmmEmitterTwoOps &Emitter) { |
543 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 602 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
544 intptr_t StartPosition = Asm->GetPosition(); | 603 intptr_t StartPosition = Asm->GetPosition(); |
545 assert(Var->hasReg()); | 604 assert(Var->hasReg()); |
546 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); | 605 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); |
547 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { | 606 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
548 if (SrcVar->hasReg()) { | 607 if (SrcVar->hasReg()) { |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
684 template <> | 743 template <> |
685 const x86::AssemblerX86::GPREmitterRegOp InstX8632Sbb::Emitter = { | 744 const x86::AssemblerX86::GPREmitterRegOp InstX8632Sbb::Emitter = { |
686 &x86::AssemblerX86::sbb, &x86::AssemblerX86::sbb, &x86::AssemblerX86::sbb}; | 745 &x86::AssemblerX86::sbb, &x86::AssemblerX86::sbb, &x86::AssemblerX86::sbb}; |
687 template <> | 746 template <> |
688 const x86::AssemblerX86::GPREmitterRegOp InstX8632Sub::Emitter = { | 747 const x86::AssemblerX86::GPREmitterRegOp InstX8632Sub::Emitter = { |
689 &x86::AssemblerX86::sub, &x86::AssemblerX86::sub, &x86::AssemblerX86::sub}; | 748 &x86::AssemblerX86::sub, &x86::AssemblerX86::sub, &x86::AssemblerX86::sub}; |
690 template <> | 749 template <> |
691 const x86::AssemblerX86::GPREmitterRegOp InstX8632Xor::Emitter = { | 750 const x86::AssemblerX86::GPREmitterRegOp InstX8632Xor::Emitter = { |
692 &x86::AssemblerX86::Xor, &x86::AssemblerX86::Xor, &x86::AssemblerX86::Xor}; | 751 &x86::AssemblerX86::Xor, &x86::AssemblerX86::Xor, &x86::AssemblerX86::Xor}; |
693 | 752 |
| 753 // Binary Shift GPR ops |
| 754 template <> |
| 755 const x86::AssemblerX86::GPREmitterShiftOp InstX8632Rol::Emitter = { |
| 756 &x86::AssemblerX86::rol, &x86::AssemblerX86::rol}; |
| 757 template <> |
| 758 const x86::AssemblerX86::GPREmitterShiftOp InstX8632Sar::Emitter = { |
| 759 &x86::AssemblerX86::sar, &x86::AssemblerX86::sar}; |
| 760 template <> |
| 761 const x86::AssemblerX86::GPREmitterShiftOp InstX8632Shl::Emitter = { |
| 762 &x86::AssemblerX86::shl, &x86::AssemblerX86::shl}; |
| 763 template <> |
| 764 const x86::AssemblerX86::GPREmitterShiftOp InstX8632Shr::Emitter = { |
| 765 &x86::AssemblerX86::shr, &x86::AssemblerX86::shr}; |
| 766 |
694 // Binary XMM ops | 767 // Binary XMM ops |
695 template <> | 768 template <> |
696 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Addss::Emitter = { | 769 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Addss::Emitter = { |
697 &x86::AssemblerX86::addss, &x86::AssemblerX86::addss, NULL}; | 770 &x86::AssemblerX86::addss, &x86::AssemblerX86::addss, NULL}; |
698 template <> | 771 template <> |
699 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Addps::Emitter = { | 772 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Addps::Emitter = { |
700 &x86::AssemblerX86::addps, &x86::AssemblerX86::addps, NULL}; | 773 &x86::AssemblerX86::addps, &x86::AssemblerX86::addps, NULL}; |
701 template <> | 774 template <> |
702 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Divss::Emitter = { | 775 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Divss::Emitter = { |
703 &x86::AssemblerX86::divss, &x86::AssemblerX86::divss, NULL}; | 776 &x86::AssemblerX86::divss, &x86::AssemblerX86::divss, NULL}; |
(...skipping 15 matching lines...) Expand all Loading... |
719 template <> | 792 template <> |
720 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pandn::Emitter = { | 793 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pandn::Emitter = { |
721 &x86::AssemblerX86::pandn, &x86::AssemblerX86::pandn, NULL}; | 794 &x86::AssemblerX86::pandn, &x86::AssemblerX86::pandn, NULL}; |
722 template <> | 795 template <> |
723 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pcmpeq::Emitter = { | 796 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pcmpeq::Emitter = { |
724 &x86::AssemblerX86::pcmpeq, &x86::AssemblerX86::pcmpeq, NULL}; | 797 &x86::AssemblerX86::pcmpeq, &x86::AssemblerX86::pcmpeq, NULL}; |
725 template <> | 798 template <> |
726 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pcmpgt::Emitter = { | 799 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pcmpgt::Emitter = { |
727 &x86::AssemblerX86::pcmpgt, &x86::AssemblerX86::pcmpgt, NULL}; | 800 &x86::AssemblerX86::pcmpgt, &x86::AssemblerX86::pcmpgt, NULL}; |
728 template <> | 801 template <> |
| 802 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pmull::Emitter = { |
| 803 &x86::AssemblerX86::pmull, &x86::AssemblerX86::pmull, NULL}; |
| 804 template <> |
729 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pmuludq::Emitter = { | 805 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pmuludq::Emitter = { |
730 &x86::AssemblerX86::pmuludq, &x86::AssemblerX86::pmuludq, NULL}; | 806 &x86::AssemblerX86::pmuludq, &x86::AssemblerX86::pmuludq, NULL}; |
731 template <> | 807 template <> |
732 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Por::Emitter = { | 808 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Por::Emitter = { |
733 &x86::AssemblerX86::por, &x86::AssemblerX86::por, NULL}; | 809 &x86::AssemblerX86::por, &x86::AssemblerX86::por, NULL}; |
734 template <> | 810 template <> |
735 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Psub::Emitter = { | 811 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Psub::Emitter = { |
736 &x86::AssemblerX86::psub, &x86::AssemblerX86::psub, NULL}; | 812 &x86::AssemblerX86::psub, &x86::AssemblerX86::psub, NULL}; |
737 template <> | 813 template <> |
738 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pxor::Emitter = { | 814 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pxor::Emitter = { |
739 &x86::AssemblerX86::pxor, &x86::AssemblerX86::pxor, NULL}; | 815 &x86::AssemblerX86::pxor, &x86::AssemblerX86::pxor, NULL}; |
740 template <> | 816 template <> |
741 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Subss::Emitter = { | 817 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Subss::Emitter = { |
742 &x86::AssemblerX86::subss, &x86::AssemblerX86::subss, NULL}; | 818 &x86::AssemblerX86::subss, &x86::AssemblerX86::subss, NULL}; |
743 template <> | 819 template <> |
744 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Subps::Emitter = { | 820 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Subps::Emitter = { |
745 &x86::AssemblerX86::subps, &x86::AssemblerX86::subps, NULL}; | 821 &x86::AssemblerX86::subps, &x86::AssemblerX86::subps, NULL}; |
746 | 822 |
| 823 // Binary XMM Shift ops |
| 824 template <> |
| 825 const x86::AssemblerX86::XmmEmitterShiftOp InstX8632Psll::Emitter = { |
| 826 &x86::AssemblerX86::psll, &x86::AssemblerX86::psll, |
| 827 &x86::AssemblerX86::psll}; |
| 828 template <> |
| 829 const x86::AssemblerX86::XmmEmitterShiftOp InstX8632Psra::Emitter = { |
| 830 &x86::AssemblerX86::psra, &x86::AssemblerX86::psra, |
| 831 &x86::AssemblerX86::psra}; |
| 832 |
747 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const { | 833 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const { |
748 Ostream &Str = Func->getContext()->getStrEmit(); | 834 Ostream &Str = Func->getContext()->getStrEmit(); |
749 assert(getSrcSize() == 1); | 835 assert(getSrcSize() == 1); |
750 Type Ty = getSrc(0)->getType(); | 836 Type Ty = getSrc(0)->getType(); |
751 assert(isScalarFloatingType(Ty)); | 837 assert(isScalarFloatingType(Ty)); |
752 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t"; | 838 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t"; |
753 getDest()->emit(Func); | 839 getDest()->emit(Func); |
754 Str << ", "; | 840 Str << ", "; |
755 getSrc(0)->emit(Func); | 841 getSrc(0)->emit(Func); |
756 Str << "\n"; | 842 Str << "\n"; |
(...skipping 23 matching lines...) Expand all Loading... |
780 TargetX8632::SSE4_1; | 866 TargetX8632::SSE4_1; |
781 (void)TypesAreValid; | 867 (void)TypesAreValid; |
782 (void)InstructionSetIsValid; | 868 (void)InstructionSetIsValid; |
783 assert(TypesAreValid); | 869 assert(TypesAreValid); |
784 assert(InstructionSetIsValid); | 870 assert(InstructionSetIsValid); |
785 snprintf(buf, llvm::array_lengthof(buf), "pmull%s", | 871 snprintf(buf, llvm::array_lengthof(buf), "pmull%s", |
786 TypeX8632Attributes[getDest()->getType()].PackString); | 872 TypeX8632Attributes[getDest()->getType()].PackString); |
787 emitTwoAddress(buf, this, Func); | 873 emitTwoAddress(buf, this, Func); |
788 } | 874 } |
789 | 875 |
| 876 template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const { |
| 877 Type Ty = getDest()->getType(); |
| 878 bool TypesAreValid = Ty == IceType_v4i32 || Ty == IceType_v8i16; |
| 879 bool InstructionSetIsValid = |
| 880 Ty == IceType_v8i16 || |
| 881 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
| 882 TargetX8632::SSE4_1; |
| 883 (void)TypesAreValid; |
| 884 (void)InstructionSetIsValid; |
| 885 assert(TypesAreValid); |
| 886 assert(InstructionSetIsValid); |
| 887 assert(getSrcSize() == 2); |
| 888 Type ElementTy = typeElementType(Ty); |
| 889 emitIASVarOperandTyXMM(Func, ElementTy, getDest(), getSrc(1), Emitter); |
| 890 } |
| 891 |
790 template <> void InstX8632Subss::emit(const Cfg *Func) const { | 892 template <> void InstX8632Subss::emit(const Cfg *Func) const { |
791 char buf[30]; | 893 char buf[30]; |
792 snprintf(buf, llvm::array_lengthof(buf), "sub%s", | 894 snprintf(buf, llvm::array_lengthof(buf), "sub%s", |
793 TypeX8632Attributes[getDest()->getType()].SdSsString); | 895 TypeX8632Attributes[getDest()->getType()].SdSsString); |
794 emitTwoAddress(buf, this, Func); | 896 emitTwoAddress(buf, this, Func); |
795 } | 897 } |
796 | 898 |
797 template <> void InstX8632Psub::emit(const Cfg *Func) const { | 899 template <> void InstX8632Psub::emit(const Cfg *Func) const { |
798 char buf[30]; | 900 char buf[30]; |
799 snprintf(buf, llvm::array_lengthof(buf), "psub%s", | 901 snprintf(buf, llvm::array_lengthof(buf), "psub%s", |
(...skipping 1282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2082 } | 2184 } |
2083 Str << "("; | 2185 Str << "("; |
2084 if (Func) | 2186 if (Func) |
2085 Var->dump(Func); | 2187 Var->dump(Func); |
2086 else | 2188 else |
2087 Var->dump(Str); | 2189 Var->dump(Str); |
2088 Str << ")"; | 2190 Str << ")"; |
2089 } | 2191 } |
2090 | 2192 |
2091 } // end of namespace Ice | 2193 } // end of namespace Ice |
OLD | NEW |