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 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 Variable *Eax, Variable *Desired, | 206 Variable *Eax, Variable *Desired, |
207 bool Locked) | 207 bool Locked) |
208 : InstX8632Lockable(Func, InstX8632::Cmpxchg, 3, | 208 : InstX8632Lockable(Func, InstX8632::Cmpxchg, 3, |
209 llvm::dyn_cast<Variable>(DestOrAddr), Locked) { | 209 llvm::dyn_cast<Variable>(DestOrAddr), Locked) { |
210 assert(Eax->getRegNum() == RegX8632::Reg_eax); | 210 assert(Eax->getRegNum() == RegX8632::Reg_eax); |
211 addSource(DestOrAddr); | 211 addSource(DestOrAddr); |
212 addSource(Eax); | 212 addSource(Eax); |
213 addSource(Desired); | 213 addSource(Desired); |
214 } | 214 } |
215 | 215 |
216 InstX8632Cmpxchg8b::InstX8632Cmpxchg8b(Cfg *Func, OperandX8632 *Addr, | 216 InstX8632Cmpxchg8b::InstX8632Cmpxchg8b(Cfg *Func, OperandX8632Mem *Addr, |
217 Variable *Edx, Variable *Eax, | 217 Variable *Edx, Variable *Eax, |
218 Variable *Ecx, Variable *Ebx, | 218 Variable *Ecx, Variable *Ebx, |
219 bool Locked) | 219 bool Locked) |
220 : InstX8632Lockable(Func, InstX8632::Cmpxchg, 5, NULL, Locked) { | 220 : InstX8632Lockable(Func, InstX8632::Cmpxchg, 5, NULL, Locked) { |
221 assert(Edx->getRegNum() == RegX8632::Reg_edx); | 221 assert(Edx->getRegNum() == RegX8632::Reg_edx); |
222 assert(Eax->getRegNum() == RegX8632::Reg_eax); | 222 assert(Eax->getRegNum() == RegX8632::Reg_eax); |
223 assert(Ecx->getRegNum() == RegX8632::Reg_ecx); | 223 assert(Ecx->getRegNum() == RegX8632::Reg_ecx); |
224 assert(Ebx->getRegNum() == RegX8632::Reg_ebx); | 224 assert(Ebx->getRegNum() == RegX8632::Reg_ebx); |
225 addSource(Addr); | 225 addSource(Addr); |
226 addSource(Edx); | 226 addSource(Edx); |
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
803 assert(getDest()->getRegNum() == RegX8632::Reg_edx); | 803 assert(getDest()->getRegNum() == RegX8632::Reg_edx); |
804 Str << "\tcwd\n"; | 804 Str << "\tcwd\n"; |
805 break; | 805 break; |
806 case IceType_i32: | 806 case IceType_i32: |
807 assert(getDest()->getRegNum() == RegX8632::Reg_edx); | 807 assert(getDest()->getRegNum() == RegX8632::Reg_edx); |
808 Str << "\tcdq\n"; | 808 Str << "\tcdq\n"; |
809 break; | 809 break; |
810 } | 810 } |
811 } | 811 } |
812 | 812 |
| 813 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const { |
| 814 Ostream &Str = Func->getContext()->getStrEmit(); |
| 815 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 816 intptr_t StartPosition = Asm->GetPosition(); |
| 817 assert(getSrcSize() == 1); |
| 818 Operand *Src0 = getSrc(0); |
| 819 assert(llvm::isa<Variable>(Src0)); |
| 820 assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax); |
| 821 switch (Src0->getType()) { |
| 822 default: |
| 823 llvm_unreachable("unexpected source type!"); |
| 824 break; |
| 825 case IceType_i8: |
| 826 assert(getDest()->getRegNum() == RegX8632::Reg_eax); |
| 827 Asm->cbw(); |
| 828 break; |
| 829 case IceType_i16: |
| 830 assert(getDest()->getRegNum() == RegX8632::Reg_edx); |
| 831 Asm->cwd(); |
| 832 break; |
| 833 case IceType_i32: |
| 834 assert(getDest()->getRegNum() == RegX8632::Reg_edx); |
| 835 Asm->cdq(); |
| 836 break; |
| 837 } |
| 838 emitIASBytes(Str, Asm, StartPosition); |
| 839 } |
| 840 |
813 void InstX8632Mul::emit(const Cfg *Func) const { | 841 void InstX8632Mul::emit(const Cfg *Func) const { |
814 Ostream &Str = Func->getContext()->getStrEmit(); | 842 Ostream &Str = Func->getContext()->getStrEmit(); |
815 assert(getSrcSize() == 2); | 843 assert(getSrcSize() == 2); |
816 assert(llvm::isa<Variable>(getSrc(0))); | 844 assert(llvm::isa<Variable>(getSrc(0))); |
817 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); | 845 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); |
818 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? | 846 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? |
819 Str << "\tmul\t"; | 847 Str << "\tmul\t"; |
820 getSrc(1)->emit(Func); | 848 getSrc(1)->emit(Func); |
821 Str << "\n"; | 849 Str << "\n"; |
822 } | 850 } |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
885 Str << "\t"; | 913 Str << "\t"; |
886 assert(Condition != CondX86::Br_None); | 914 assert(Condition != CondX86::Br_None); |
887 assert(getDest()->hasReg()); | 915 assert(getDest()->hasReg()); |
888 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "\t"; | 916 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "\t"; |
889 getDest()->emit(Func); | 917 getDest()->emit(Func); |
890 Str << ", "; | 918 Str << ", "; |
891 getSrc(1)->emit(Func); | 919 getSrc(1)->emit(Func); |
892 Str << "\n"; | 920 Str << "\n"; |
893 } | 921 } |
894 | 922 |
| 923 void InstX8632Cmov::emitIAS(const Cfg *Func) const { |
| 924 Ostream &Str = Func->getContext()->getStrEmit(); |
| 925 Str << "\t"; |
| 926 assert(Condition != CondX86::Br_None); |
| 927 assert(getDest()->hasReg()); |
| 928 assert(getSrcSize() == 2); |
| 929 // Only need the reg/reg form now. |
| 930 const Variable *Src = llvm::cast<Variable>(getSrc(1)); |
| 931 assert(Src->hasReg()); |
| 932 assert(Src->getType() == IceType_i32); |
| 933 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 934 intptr_t StartPosition = Asm->GetPosition(); |
| 935 Asm->cmov(Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()), |
| 936 RegX8632::getEncodedGPR(Src->getRegNum())); |
| 937 emitIASBytes(Str, Asm, StartPosition); |
| 938 } |
| 939 |
895 void InstX8632Cmov::dump(const Cfg *Func) const { | 940 void InstX8632Cmov::dump(const Cfg *Func) const { |
896 Ostream &Str = Func->getContext()->getStrDump(); | 941 Ostream &Str = Func->getContext()->getStrDump(); |
897 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; | 942 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; |
898 Str << getDest()->getType() << " "; | 943 Str << getDest()->getType() << " "; |
899 dumpDest(Func); | 944 dumpDest(Func); |
900 Str << ", "; | 945 Str << ", "; |
901 dumpSources(Func); | 946 dumpSources(Func); |
902 } | 947 } |
903 | 948 |
904 void InstX8632Cmpps::emit(const Cfg *Func) const { | 949 void InstX8632Cmpps::emit(const Cfg *Func) const { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
951 if (Locked) { | 996 if (Locked) { |
952 Str << "\tlock"; | 997 Str << "\tlock"; |
953 } | 998 } |
954 Str << "\tcmpxchg\t"; | 999 Str << "\tcmpxchg\t"; |
955 getSrc(0)->emit(Func); | 1000 getSrc(0)->emit(Func); |
956 Str << ", "; | 1001 Str << ", "; |
957 getSrc(2)->emit(Func); | 1002 getSrc(2)->emit(Func); |
958 Str << "\n"; | 1003 Str << "\n"; |
959 } | 1004 } |
960 | 1005 |
| 1006 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const { |
| 1007 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1008 assert(getSrcSize() == 3); |
| 1009 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1010 intptr_t StartPosition = Asm->GetPosition(); |
| 1011 Type Ty = getSrc(0)->getType(); |
| 1012 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
| 1013 const x86::Address Addr = Mem->toAsmAddress(Asm); |
| 1014 const Variable *VarReg = llvm::cast<Variable>(getSrc(2)); |
| 1015 assert(VarReg->hasReg()); |
| 1016 const RegX8632::GPRRegister Reg = |
| 1017 RegX8632::getEncodedGPR(VarReg->getRegNum()); |
| 1018 if (Locked) { |
| 1019 Asm->LockCmpxchg(Ty, Addr, Reg); |
| 1020 } else { |
| 1021 Asm->cmpxchg(Ty, Addr, Reg); |
| 1022 } |
| 1023 emitIASBytes(Str, Asm, StartPosition); |
| 1024 } |
| 1025 |
961 void InstX8632Cmpxchg::dump(const Cfg *Func) const { | 1026 void InstX8632Cmpxchg::dump(const Cfg *Func) const { |
962 Ostream &Str = Func->getContext()->getStrDump(); | 1027 Ostream &Str = Func->getContext()->getStrDump(); |
963 if (Locked) { | 1028 if (Locked) { |
964 Str << "lock "; | 1029 Str << "lock "; |
965 } | 1030 } |
966 Str << "cmpxchg." << getSrc(0)->getType() << " "; | 1031 Str << "cmpxchg." << getSrc(0)->getType() << " "; |
967 dumpSources(Func); | 1032 dumpSources(Func); |
968 } | 1033 } |
969 | 1034 |
970 void InstX8632Cmpxchg8b::emit(const Cfg *Func) const { | 1035 void InstX8632Cmpxchg8b::emit(const Cfg *Func) const { |
971 Ostream &Str = Func->getContext()->getStrEmit(); | 1036 Ostream &Str = Func->getContext()->getStrEmit(); |
972 assert(getSrcSize() == 5); | 1037 assert(getSrcSize() == 5); |
973 if (Locked) { | 1038 if (Locked) { |
974 Str << "\tlock"; | 1039 Str << "\tlock"; |
975 } | 1040 } |
976 Str << "\tcmpxchg8b\t"; | 1041 Str << "\tcmpxchg8b\t"; |
977 getSrc(0)->emit(Func); | 1042 getSrc(0)->emit(Func); |
978 Str << "\n"; | 1043 Str << "\n"; |
979 } | 1044 } |
980 | 1045 |
| 1046 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const { |
| 1047 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1048 assert(getSrcSize() == 5); |
| 1049 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1050 intptr_t StartPosition = Asm->GetPosition(); |
| 1051 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
| 1052 const x86::Address Addr = Mem->toAsmAddress(Asm); |
| 1053 if (Locked) { |
| 1054 Asm->lock(); |
| 1055 } |
| 1056 Asm->cmpxchg8b(Addr); |
| 1057 emitIASBytes(Str, Asm, StartPosition); |
| 1058 } |
| 1059 |
981 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const { | 1060 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const { |
982 Ostream &Str = Func->getContext()->getStrDump(); | 1061 Ostream &Str = Func->getContext()->getStrDump(); |
983 if (Locked) { | 1062 if (Locked) { |
984 Str << "lock "; | 1063 Str << "lock "; |
985 } | 1064 } |
986 Str << "cmpxchg8b "; | 1065 Str << "cmpxchg8b "; |
987 dumpSources(Func); | 1066 dumpSources(Func); |
988 } | 1067 } |
989 | 1068 |
990 void InstX8632Cvt::emit(const Cfg *Func) const { | 1069 void InstX8632Cvt::emit(const Cfg *Func) const { |
(...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1566 if (Locked) { | 1645 if (Locked) { |
1567 Str << "\tlock"; | 1646 Str << "\tlock"; |
1568 } | 1647 } |
1569 Str << "\txadd\t"; | 1648 Str << "\txadd\t"; |
1570 getSrc(0)->emit(Func); | 1649 getSrc(0)->emit(Func); |
1571 Str << ", "; | 1650 Str << ", "; |
1572 getSrc(1)->emit(Func); | 1651 getSrc(1)->emit(Func); |
1573 Str << "\n"; | 1652 Str << "\n"; |
1574 } | 1653 } |
1575 | 1654 |
| 1655 void InstX8632Xadd::emitIAS(const Cfg *Func) const { |
| 1656 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1657 assert(getSrcSize() == 2); |
| 1658 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1659 intptr_t StartPosition = Asm->GetPosition(); |
| 1660 Type Ty = getSrc(0)->getType(); |
| 1661 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
| 1662 const x86::Address Addr = Mem->toAsmAddress(Asm); |
| 1663 const Variable *VarReg = llvm::cast<Variable>(getSrc(1)); |
| 1664 assert(VarReg->hasReg()); |
| 1665 const RegX8632::GPRRegister Reg = |
| 1666 RegX8632::getEncodedGPR(VarReg->getRegNum()); |
| 1667 if (Locked) { |
| 1668 Asm->lock(); |
| 1669 } |
| 1670 Asm->xadd(Ty, Addr, Reg); |
| 1671 emitIASBytes(Str, Asm, StartPosition); |
| 1672 } |
| 1673 |
1576 void InstX8632Xadd::dump(const Cfg *Func) const { | 1674 void InstX8632Xadd::dump(const Cfg *Func) const { |
1577 Ostream &Str = Func->getContext()->getStrDump(); | 1675 Ostream &Str = Func->getContext()->getStrDump(); |
1578 if (Locked) { | 1676 if (Locked) { |
1579 Str << "lock "; | 1677 Str << "lock "; |
1580 } | 1678 } |
1581 Type Ty = getSrc(0)->getType(); | 1679 Type Ty = getSrc(0)->getType(); |
1582 Str << "xadd." << Ty << " "; | 1680 Str << "xadd." << Ty << " "; |
1583 dumpSources(Func); | 1681 dumpSources(Func); |
1584 } | 1682 } |
1585 | 1683 |
1586 void InstX8632Xchg::emit(const Cfg *Func) const { | 1684 void InstX8632Xchg::emit(const Cfg *Func) const { |
1587 Ostream &Str = Func->getContext()->getStrEmit(); | 1685 Ostream &Str = Func->getContext()->getStrEmit(); |
1588 Str << "\txchg\t"; | 1686 Str << "\txchg\t"; |
1589 getSrc(0)->emit(Func); | 1687 getSrc(0)->emit(Func); |
1590 Str << ", "; | 1688 Str << ", "; |
1591 getSrc(1)->emit(Func); | 1689 getSrc(1)->emit(Func); |
1592 Str << "\n"; | 1690 Str << "\n"; |
1593 } | 1691 } |
1594 | 1692 |
| 1693 void InstX8632Xchg::emitIAS(const Cfg *Func) const { |
| 1694 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1695 assert(getSrcSize() == 2); |
| 1696 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1697 intptr_t StartPosition = Asm->GetPosition(); |
| 1698 Type Ty = getSrc(0)->getType(); |
| 1699 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
| 1700 const x86::Address Addr = Mem->toAsmAddress(Asm); |
| 1701 const Variable *VarReg = llvm::cast<Variable>(getSrc(1)); |
| 1702 assert(VarReg->hasReg()); |
| 1703 const RegX8632::GPRRegister Reg = |
| 1704 RegX8632::getEncodedGPR(VarReg->getRegNum()); |
| 1705 Asm->xchg(Ty, Addr, Reg); |
| 1706 emitIASBytes(Str, Asm, StartPosition); |
| 1707 } |
| 1708 |
1595 void InstX8632Xchg::dump(const Cfg *Func) const { | 1709 void InstX8632Xchg::dump(const Cfg *Func) const { |
1596 Ostream &Str = Func->getContext()->getStrDump(); | 1710 Ostream &Str = Func->getContext()->getStrDump(); |
1597 Type Ty = getSrc(0)->getType(); | 1711 Type Ty = getSrc(0)->getType(); |
1598 Str << "xchg." << Ty << " "; | 1712 Str << "xchg." << Ty << " "; |
1599 dumpSources(Func); | 1713 dumpSources(Func); |
1600 } | 1714 } |
1601 | 1715 |
1602 void OperandX8632Mem::emit(const Cfg *Func) const { | 1716 void OperandX8632Mem::emit(const Cfg *Func) const { |
1603 Ostream &Str = Func->getContext()->getStrEmit(); | 1717 Ostream &Str = Func->getContext()->getStrEmit(); |
1604 Str << TypeX8632Attributes[getType()].WidthString << " "; | 1718 Str << TypeX8632Attributes[getType()].WidthString << " "; |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1764 } | 1878 } |
1765 Str << "("; | 1879 Str << "("; |
1766 if (Func) | 1880 if (Func) |
1767 Var->dump(Func); | 1881 Var->dump(Func); |
1768 else | 1882 else |
1769 Var->dump(Str); | 1883 Var->dump(Str); |
1770 Str << ")"; | 1884 Str << ")"; |
1771 } | 1885 } |
1772 | 1886 |
1773 } // end of namespace Ice | 1887 } // end of namespace Ice |
OLD | NEW |