OLD | NEW |
---|---|
1 //===- subzero/src/IceInstARM32.cpp - ARM32 instruction implementation ----===// | 1 //===- subzero/src/IceInstARM32.cpp - ARM32 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 /// \file | 10 /// \file |
(...skipping 800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
811 Ostream &Str = Func->getContext()->getStrEmit(); | 811 Ostream &Str = Func->getContext()->getStrEmit(); |
812 Variable *DestLo = getDest(); | 812 Variable *DestLo = getDest(); |
813 Variable *DestHi = getDestHi(); | 813 Variable *DestHi = getDestHi(); |
814 auto *Src = llvm::cast<Variable>(getSrc(0)); | 814 auto *Src = llvm::cast<Variable>(getSrc(0)); |
815 | 815 |
816 assert(DestHi->hasReg()); | 816 assert(DestHi->hasReg()); |
817 assert(DestLo->hasReg()); | 817 assert(DestLo->hasReg()); |
818 assert(llvm::isa<Variable>(Src) && Src->hasReg()); | 818 assert(llvm::isa<Variable>(Src) && Src->hasReg()); |
819 | 819 |
820 Str << "\t" | 820 Str << "\t" |
821 << "vmov" << getPredicate() << "\t"; | 821 "vmov" << getPredicate() << "\t"; |
822 DestLo->emit(Func); | 822 DestLo->emit(Func); |
823 Str << ", "; | 823 Str << ", "; |
824 DestHi->emit(Func); | 824 DestHi->emit(Func); |
825 Str << ", "; | 825 Str << ", "; |
826 Src->emit(Func); | 826 Src->emit(Func); |
827 } | 827 } |
828 | 828 |
829 void InstARM32Mov::emitSingleDestMultiSource(const Cfg *Func) const { | 829 void InstARM32Mov::emitSingleDestMultiSource(const Cfg *Func) const { |
830 if (!BuildDefs::dump()) | 830 if (!BuildDefs::dump()) |
831 return; | 831 return; |
832 Ostream &Str = Func->getContext()->getStrEmit(); | 832 Ostream &Str = Func->getContext()->getStrEmit(); |
833 Variable *Dest = getDest(); | 833 Variable *Dest = getDest(); |
834 auto *SrcLo = llvm::cast<Variable>(getSrc(0)); | 834 auto *SrcLo = llvm::cast<Variable>(getSrc(0)); |
835 auto *SrcHi = llvm::cast<Variable>(getSrc(1)); | 835 auto *SrcHi = llvm::cast<Variable>(getSrc(1)); |
836 | 836 |
837 assert(SrcHi->hasReg()); | 837 assert(SrcHi->hasReg()); |
838 assert(SrcLo->hasReg()); | 838 assert(SrcLo->hasReg()); |
839 assert(Dest->hasReg()); | 839 assert(Dest->hasReg()); |
840 assert(getSrcSize() == 2); | 840 assert(getSrcSize() == 2); |
841 | 841 |
842 Str << "\t" | 842 Str << "\t" |
843 << "vmov" << getPredicate() << "\t"; | 843 "vmov" << getPredicate() << "\t"; |
844 Dest->emit(Func); | 844 Dest->emit(Func); |
845 Str << ", "; | 845 Str << ", "; |
846 SrcLo->emit(Func); | 846 SrcLo->emit(Func); |
847 Str << ", "; | 847 Str << ", "; |
848 SrcHi->emit(Func); | 848 SrcHi->emit(Func); |
849 } | 849 } |
850 | 850 |
851 namespace { | 851 namespace { |
852 | 852 |
853 bool isVariableWithoutRegister(const Operand *Op) { | 853 bool isVariableWithoutRegister(const Operand *Op) { |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
974 Str << " "; | 974 Str << " "; |
975 | 975 |
976 dumpSources(Func); | 976 dumpSources(Func); |
977 } | 977 } |
978 | 978 |
979 void InstARM32Br::emit(const Cfg *Func) const { | 979 void InstARM32Br::emit(const Cfg *Func) const { |
980 if (!BuildDefs::dump()) | 980 if (!BuildDefs::dump()) |
981 return; | 981 return; |
982 Ostream &Str = Func->getContext()->getStrEmit(); | 982 Ostream &Str = Func->getContext()->getStrEmit(); |
983 Str << "\t" | 983 Str << "\t" |
984 << "b" << getPredicate() << "\t"; | 984 "b" << getPredicate() << "\t"; |
985 if (Label) { | 985 if (Label) { |
986 Str << Label->getName(Func); | 986 Str << Label->getName(Func); |
987 } else { | 987 } else { |
988 if (isUnconditionalBranch()) { | 988 if (isUnconditionalBranch()) { |
989 Str << getTargetFalse()->getAsmName(); | 989 Str << getTargetFalse()->getAsmName(); |
990 } else { | 990 } else { |
991 Str << getTargetTrue()->getAsmName(); | 991 Str << getTargetTrue()->getAsmName(); |
992 if (getTargetFalse()) { | 992 if (getTargetFalse()) { |
993 startNextInst(Func); | 993 startNextInst(Func); |
994 Str << "\n\t" | 994 Str << "\n\t" |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1045 assert(getSrcSize() == 1); | 1045 assert(getSrcSize() == 1); |
1046 if (llvm::isa<ConstantInteger32>(getCallTarget())) { | 1046 if (llvm::isa<ConstantInteger32>(getCallTarget())) { |
1047 // This shouldn't happen (typically have to copy the full 32-bits to a | 1047 // This shouldn't happen (typically have to copy the full 32-bits to a |
1048 // register and do an indirect jump). | 1048 // register and do an indirect jump). |
1049 llvm::report_fatal_error("ARM32Call to ConstantInteger32"); | 1049 llvm::report_fatal_error("ARM32Call to ConstantInteger32"); |
1050 } else if (const auto *CallTarget = | 1050 } else if (const auto *CallTarget = |
1051 llvm::dyn_cast<ConstantRelocatable>(getCallTarget())) { | 1051 llvm::dyn_cast<ConstantRelocatable>(getCallTarget())) { |
1052 // Calls only have 24-bits, but the linker should insert veneers to extend | 1052 // Calls only have 24-bits, but the linker should insert veneers to extend |
1053 // the range if needed. | 1053 // the range if needed. |
1054 Str << "\t" | 1054 Str << "\t" |
1055 << "bl" | 1055 "bl" |
1056 << "\t"; | 1056 "\t"; |
1057 CallTarget->emitWithoutPrefix(Func->getTarget()); | 1057 CallTarget->emitWithoutPrefix(Func->getTarget()); |
1058 } else { | 1058 } else { |
1059 Str << "\t" | 1059 Str << "\t" |
1060 << "blx" | 1060 "blx" |
1061 << "\t"; | 1061 "\t"; |
1062 getCallTarget()->emit(Func); | 1062 getCallTarget()->emit(Func); |
1063 } | 1063 } |
1064 } | 1064 } |
1065 | 1065 |
1066 void InstARM32Call::emitIAS(const Cfg *Func) const { | 1066 void InstARM32Call::emitIAS(const Cfg *Func) const { |
1067 assert(getSrcSize() == 1); | 1067 assert(getSrcSize() == 1); |
1068 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 1068 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
1069 if (llvm::isa<ConstantInteger32>(getCallTarget())) { | 1069 if (llvm::isa<ConstantInteger32>(getCallTarget())) { |
1070 // This shouldn't happen (typically have to copy the full 32-bits to a | 1070 // This shouldn't happen (typically have to copy the full 32-bits to a |
1071 // register and do an indirect jump). | 1071 // register and do an indirect jump). |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1489 | 1489 |
1490 void InstARM32Ret::emit(const Cfg *Func) const { | 1490 void InstARM32Ret::emit(const Cfg *Func) const { |
1491 if (!BuildDefs::dump()) | 1491 if (!BuildDefs::dump()) |
1492 return; | 1492 return; |
1493 assert(getSrcSize() > 0); | 1493 assert(getSrcSize() > 0); |
1494 auto *LR = llvm::cast<Variable>(getSrc(0)); | 1494 auto *LR = llvm::cast<Variable>(getSrc(0)); |
1495 assert(LR->hasReg()); | 1495 assert(LR->hasReg()); |
1496 assert(LR->getRegNum() == RegARM32::Reg_lr); | 1496 assert(LR->getRegNum() == RegARM32::Reg_lr); |
1497 Ostream &Str = Func->getContext()->getStrEmit(); | 1497 Ostream &Str = Func->getContext()->getStrEmit(); |
1498 Str << "\t" | 1498 Str << "\t" |
1499 << "bx" | 1499 "bx" |
1500 << "\t"; | 1500 "\t"; |
1501 LR->emit(Func); | 1501 LR->emit(Func); |
1502 } | 1502 } |
1503 | 1503 |
1504 void InstARM32Ret::emitIAS(const Cfg *Func) const { | 1504 void InstARM32Ret::emitIAS(const Cfg *Func) const { |
1505 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 1505 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
1506 Asm->bx(RegARM32::Encoded_Reg_lr); | 1506 Asm->bx(RegARM32::Encoded_Reg_lr); |
1507 if (Asm->needsTextFixup()) | 1507 if (Asm->needsTextFixup()) |
1508 emitUsingTextFixup(Func); | 1508 emitUsingTextFixup(Func); |
1509 } | 1509 } |
1510 | 1510 |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1618 Str << "trap"; | 1618 Str << "trap"; |
1619 } | 1619 } |
1620 | 1620 |
1621 void InstARM32Umull::emit(const Cfg *Func) const { | 1621 void InstARM32Umull::emit(const Cfg *Func) const { |
1622 if (!BuildDefs::dump()) | 1622 if (!BuildDefs::dump()) |
1623 return; | 1623 return; |
1624 Ostream &Str = Func->getContext()->getStrEmit(); | 1624 Ostream &Str = Func->getContext()->getStrEmit(); |
1625 assert(getSrcSize() == 2); | 1625 assert(getSrcSize() == 2); |
1626 assert(getDest()->hasReg()); | 1626 assert(getDest()->hasReg()); |
1627 Str << "\t" | 1627 Str << "\t" |
1628 << "umull" << getPredicate() << "\t"; | 1628 "umull" << getPredicate() << "\t"; |
1629 getDest()->emit(Func); | 1629 getDest()->emit(Func); |
1630 Str << ", "; | 1630 Str << ", "; |
1631 DestHi->emit(Func); | 1631 DestHi->emit(Func); |
1632 Str << ", "; | 1632 Str << ", "; |
1633 getSrc(0)->emit(Func); | 1633 getSrc(0)->emit(Func); |
1634 Str << ", "; | 1634 Str << ", "; |
1635 getSrc(1)->emit(Func); | 1635 getSrc(1)->emit(Func); |
1636 } | 1636 } |
1637 | 1637 |
1638 void InstARM32Umull::emitIAS(const Cfg *Func) const { | 1638 void InstARM32Umull::emitIAS(const Cfg *Func) const { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1682 } | 1682 } |
1683 } // end of anonymous namespace | 1683 } // end of anonymous namespace |
1684 | 1684 |
1685 void InstARM32Vcvt::emit(const Cfg *Func) const { | 1685 void InstARM32Vcvt::emit(const Cfg *Func) const { |
1686 if (!BuildDefs::dump()) | 1686 if (!BuildDefs::dump()) |
1687 return; | 1687 return; |
1688 Ostream &Str = Func->getContext()->getStrEmit(); | 1688 Ostream &Str = Func->getContext()->getStrEmit(); |
1689 assert(getSrcSize() == 1); | 1689 assert(getSrcSize() == 1); |
1690 assert(getDest()->hasReg()); | 1690 assert(getDest()->hasReg()); |
1691 Str << "\t" | 1691 Str << "\t" |
1692 << "vcvt" << getPredicate() << vcvtVariantSuffix(Variant) << "\t"; | 1692 "vcvt" << getPredicate() << vcvtVariantSuffix(Variant) << "\t"; |
1693 getDest()->emit(Func); | 1693 getDest()->emit(Func); |
1694 Str << ", "; | 1694 Str << ", "; |
1695 getSrc(0)->emit(Func); | 1695 getSrc(0)->emit(Func); |
1696 } | 1696 } |
1697 | 1697 |
1698 void InstARM32Vcvt::dump(const Cfg *Func) const { | 1698 void InstARM32Vcvt::dump(const Cfg *Func) const { |
1699 if (!BuildDefs::dump()) | 1699 if (!BuildDefs::dump()) |
1700 return; | 1700 return; |
1701 Ostream &Str = Func->getContext()->getStrDump(); | 1701 Ostream &Str = Func->getContext()->getStrDump(); |
1702 dumpDest(Func); | 1702 dumpDest(Func); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1783 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 1783 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
1784 constexpr ARM32::IValueT SyOption = 0xF; // i.e. 1111 | 1784 constexpr ARM32::IValueT SyOption = 0xF; // i.e. 1111 |
1785 Asm->dmb(SyOption); | 1785 Asm->dmb(SyOption); |
1786 if (Asm->needsTextFixup()) | 1786 if (Asm->needsTextFixup()) |
1787 emitUsingTextFixup(Func); | 1787 emitUsingTextFixup(Func); |
1788 } | 1788 } |
1789 | 1789 |
1790 void InstARM32Dmb::dump(const Cfg *Func) const { | 1790 void InstARM32Dmb::dump(const Cfg *Func) const { |
1791 if (!BuildDefs::dump()) | 1791 if (!BuildDefs::dump()) |
1792 return; | 1792 return; |
1793 Func->getContext()->getStrDump() << "dmb\tsy"; | 1793 Func->getContext()->getStrDump() << "dmb\t" |
1794 << "sy"; | |
Karl
2015/12/15 17:33:10
Slight inconsistency here? dmb is the the opcode.
Jim Stichnoth
2015/12/16 14:05:12
Done.
| |
1794 } | 1795 } |
1795 | 1796 |
1796 void OperandARM32Mem::emit(const Cfg *Func) const { | 1797 void OperandARM32Mem::emit(const Cfg *Func) const { |
1797 if (!BuildDefs::dump()) | 1798 if (!BuildDefs::dump()) |
1798 return; | 1799 return; |
1799 Ostream &Str = Func->getContext()->getStrEmit(); | 1800 Ostream &Str = Func->getContext()->getStrEmit(); |
1800 Str << "["; | 1801 Str << "["; |
1801 getBase()->emit(Func); | 1802 getBase()->emit(Func); |
1802 switch (getAddrMode()) { | 1803 switch (getAddrMode()) { |
1803 case PostIndex: | 1804 case PostIndex: |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2035 template class InstARM32UnaryopFP<InstARM32::Vsqrt>; | 2036 template class InstARM32UnaryopFP<InstARM32::Vsqrt>; |
2036 | 2037 |
2037 template class InstARM32FourAddrGPR<InstARM32::Mla>; | 2038 template class InstARM32FourAddrGPR<InstARM32::Mla>; |
2038 template class InstARM32FourAddrGPR<InstARM32::Mls>; | 2039 template class InstARM32FourAddrGPR<InstARM32::Mls>; |
2039 | 2040 |
2040 template class InstARM32CmpLike<InstARM32::Cmn>; | 2041 template class InstARM32CmpLike<InstARM32::Cmn>; |
2041 template class InstARM32CmpLike<InstARM32::Cmp>; | 2042 template class InstARM32CmpLike<InstARM32::Cmp>; |
2042 template class InstARM32CmpLike<InstARM32::Tst>; | 2043 template class InstARM32CmpLike<InstARM32::Tst>; |
2043 | 2044 |
2044 } // end of namespace Ice | 2045 } // end of namespace Ice |
OLD | NEW |