| 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 |