Chromium Code Reviews| 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 |