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 682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
693 | 693 |
694 } // end of anonymous namespace | 694 } // end of anonymous namespace |
695 | 695 |
696 void InstARM32Mov::emitSingleDestSingleSource(const Cfg *Func) const { | 696 void InstARM32Mov::emitSingleDestSingleSource(const Cfg *Func) const { |
697 if (!BuildDefs::dump()) | 697 if (!BuildDefs::dump()) |
698 return; | 698 return; |
699 Ostream &Str = Func->getContext()->getStrEmit(); | 699 Ostream &Str = Func->getContext()->getStrEmit(); |
700 Variable *Dest = getDest(); | 700 Variable *Dest = getDest(); |
701 | 701 |
702 if (Dest->hasReg()) { | 702 if (Dest->hasReg()) { |
703 Type DestTy = Dest->getType(); | 703 Type Ty = Dest->getType(); |
704 Operand *Src0 = getSrc(0); | 704 Operand *Src0 = getSrc(0); |
705 const bool DestIsVector = isVectorType(DestTy); | 705 const bool IsVector = isVectorType(Ty); |
706 const bool DestIsScalarFP = isScalarFloatingType(Dest->getType()); | 706 const bool IsScalarFP = isScalarFloatingType(Ty); |
707 const bool CoreVFPMove = isMoveBetweenCoreAndVFPRegisters(Dest, Src0); | 707 const bool CoreVFPMove = isMoveBetweenCoreAndVFPRegisters(Dest, Src0); |
708 const char *LoadOpcode = | 708 const char *LoadOpcode = IsVector ? "vld1" : (IsScalarFP ? "vldr" : "ldr"); |
709 DestIsVector ? "vld1" : (DestIsScalarFP ? "vldr" : "ldr"); | 709 const bool IsVMove = (IsVector || IsScalarFP || CoreVFPMove); |
710 const char *RegMovOpcode = | 710 const char *RegMovOpcode = IsVMove ? "vmov" : "mov"; |
711 (DestIsVector || DestIsScalarFP || CoreVFPMove) ? "vmov" : "mov"; | |
712 const char *ActualOpcode = isMemoryAccess(Src0) ? LoadOpcode : RegMovOpcode; | 711 const char *ActualOpcode = isMemoryAccess(Src0) ? LoadOpcode : RegMovOpcode; |
713 // when vmov{c}'ing, we need to emit a width string. Otherwise, the | 712 // when vmov{c}'ing, we need to emit a width string. Otherwise, the |
714 // assembler might be tempted to assume we want a vector vmov{c}, and that | 713 // assembler might be tempted to assume we want a vector vmov{c}, and that |
715 // is disallowed because ARM. | 714 // is disallowed because ARM. |
716 const char *NoWidthString = ""; | 715 const char *NoWidthString = ""; |
717 const char *WidthString = | 716 const char *WidthString = |
718 isMemoryAccess(Src0) | 717 isMemoryAccess(Src0) |
719 ? (DestIsVector ? ".64" : NoWidthString) | 718 ? (IsVector ? ".64" : getWidthString(Ty)) |
720 : (!CoreVFPMove ? getVecWidthString(DestTy) : NoWidthString); | 719 : (!CoreVFPMove ? getVecWidthString(Ty) : NoWidthString); |
721 | 720 Str << "\t" << ActualOpcode; |
722 Str << "\t" << ActualOpcode << getPredicate() << WidthString << "\t"; | 721 const bool IsVInst = IsVMove || IsVector || IsScalarFP; |
| 722 if (IsVInst) { |
| 723 Str << getPredicate() << WidthString; |
| 724 } else { |
| 725 Str << WidthString << getPredicate(); |
| 726 } |
| 727 Str << "\t"; |
723 Dest->emit(Func); | 728 Dest->emit(Func); |
724 Str << ", "; | 729 Str << ", "; |
725 Src0->emit(Func); | 730 Src0->emit(Func); |
726 } else { | 731 } else { |
727 Variable *Src0 = llvm::cast<Variable>(getSrc(0)); | 732 Variable *Src0 = llvm::cast<Variable>(getSrc(0)); |
728 assert(Src0->hasReg()); | 733 assert(Src0->hasReg()); |
| 734 Type Ty = Src0->getType(); |
| 735 const bool IsVector = isVectorType(Ty); |
| 736 const bool IsScalarFP = isScalarFloatingType(Ty); |
729 const char *ActualOpcode = | 737 const char *ActualOpcode = |
730 isVectorType(Src0->getType()) | 738 IsVector ? "vst1" : (IsScalarFP ? "vstr" : "str"); |
731 ? "vst1" | 739 const char *WidthString = IsVector ? ".64" : getWidthString(Ty); |
732 : (isScalarFloatingType(Src0->getType()) ? "vstr" : "str"); | 740 Str << "\t" << ActualOpcode; |
733 const char *NoWidthString = ""; | 741 const bool IsVInst = IsVector || IsScalarFP; |
734 const char *WidthString = | 742 if (IsVInst) { |
735 isVectorType(Src0->getType()) ? ".64" : NoWidthString; | 743 Str << getPredicate() << WidthString; |
736 Str << "\t" << ActualOpcode << getPredicate() << WidthString << "\t"; | 744 } else { |
| 745 Str << WidthString << getPredicate(); |
| 746 } |
| 747 Str << "\t"; |
737 Src0->emit(Func); | 748 Src0->emit(Func); |
738 Str << ", "; | 749 Str << ", "; |
739 Dest->emit(Func); | 750 Dest->emit(Func); |
740 } | 751 } |
741 } | 752 } |
742 | 753 |
743 void InstARM32Mov::emitIASSingleDestSingleSource(const Cfg *Func) const { | 754 void InstARM32Mov::emitIASSingleDestSingleSource(const Cfg *Func) const { |
744 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 755 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
745 Variable *Dest = getDest(); | 756 Variable *Dest = getDest(); |
746 Operand *Src0 = getSrc(0); | 757 Operand *Src0 = getSrc(0); |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
948 emitUsingTextFixup(Func); | 959 emitUsingTextFixup(Func); |
949 } | 960 } |
950 | 961 |
951 template <> void InstARM32Ldr::emit(const Cfg *Func) const { | 962 template <> void InstARM32Ldr::emit(const Cfg *Func) const { |
952 if (!BuildDefs::dump()) | 963 if (!BuildDefs::dump()) |
953 return; | 964 return; |
954 Ostream &Str = Func->getContext()->getStrEmit(); | 965 Ostream &Str = Func->getContext()->getStrEmit(); |
955 assert(getSrcSize() == 1); | 966 assert(getSrcSize() == 1); |
956 assert(getDest()->hasReg()); | 967 assert(getDest()->hasReg()); |
957 Variable *Dest = getDest(); | 968 Variable *Dest = getDest(); |
958 Type DestTy = Dest->getType(); | 969 Type Ty = Dest->getType(); |
959 const bool DestIsVector = isVectorType(DestTy); | 970 const bool IsVector = isVectorType(Ty); |
960 const bool DestIsScalarFloat = isScalarFloatingType(DestTy); | 971 const bool IsScalarFloat = isScalarFloatingType(Ty); |
961 const char *ActualOpcode = | 972 const char *ActualOpcode = |
962 DestIsVector ? "vld1" : (DestIsScalarFloat ? "vldr" : "ldr"); | 973 IsVector ? "vld1" : (IsScalarFloat ? "vldr" : "ldr"); |
963 const char *VectorMarker = DestIsVector ? ".64" : ""; | 974 const char *VectorMarker = IsVector ? ".64" : ""; |
964 const char *WidthString = DestIsVector ? "" : getWidthString(DestTy); | 975 const char *WidthString = IsVector ? "" : getWidthString(Ty); |
965 Str << "\t" << ActualOpcode << WidthString << getPredicate() << VectorMarker | 976 Str << "\t" << ActualOpcode; |
966 << "\t"; | 977 const bool IsVInst = IsVector || IsScalarFloat; |
| 978 if (IsVInst) { |
| 979 Str << getPredicate() << WidthString; |
| 980 } else { |
| 981 Str << WidthString << getPredicate(); |
| 982 } |
| 983 Str << VectorMarker << "\t"; |
967 getDest()->emit(Func); | 984 getDest()->emit(Func); |
968 Str << ", "; | 985 Str << ", "; |
969 getSrc(0)->emit(Func); | 986 getSrc(0)->emit(Func); |
970 } | 987 } |
971 | 988 |
972 template <> void InstARM32Ldr::emitIAS(const Cfg *Func) const { | 989 template <> void InstARM32Ldr::emitIAS(const Cfg *Func) const { |
973 assert(getSrcSize() == 1); | 990 assert(getSrcSize() == 1); |
974 Variable *Dest = getDest(); | 991 Variable *Dest = getDest(); |
975 Type DestTy = Dest->getType(); | 992 Type DestTy = Dest->getType(); |
976 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 993 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1263 dumpSources(Func); | 1280 dumpSources(Func); |
1264 } | 1281 } |
1265 | 1282 |
1266 void InstARM32Str::emit(const Cfg *Func) const { | 1283 void InstARM32Str::emit(const Cfg *Func) const { |
1267 if (!BuildDefs::dump()) | 1284 if (!BuildDefs::dump()) |
1268 return; | 1285 return; |
1269 Ostream &Str = Func->getContext()->getStrEmit(); | 1286 Ostream &Str = Func->getContext()->getStrEmit(); |
1270 assert(getSrcSize() == 2); | 1287 assert(getSrcSize() == 2); |
1271 Type Ty = getSrc(0)->getType(); | 1288 Type Ty = getSrc(0)->getType(); |
1272 const bool IsVectorStore = isVectorType(Ty); | 1289 const bool IsVectorStore = isVectorType(Ty); |
| 1290 const bool IsScalarFloat = isScalarFloatingType(Ty); |
1273 const char *Opcode = | 1291 const char *Opcode = |
1274 IsVectorStore ? "vst1" : (isScalarFloatingType(Ty) ? "vstr" : "str"); | 1292 IsVectorStore ? "vst1" : (IsScalarFloat ? "vstr" : "str"); |
1275 const char *VecEltWidthString = IsVectorStore ? ".64" : ""; | 1293 const char *VecEltWidthString = IsVectorStore ? ".64" : ""; |
1276 Str << "\t" << Opcode << getWidthString(Ty) << getPredicate() | 1294 Str << "\t" << Opcode; |
1277 << VecEltWidthString << "\t"; | 1295 const bool IsVInst = IsVectorStore || IsScalarFloat; |
| 1296 if (IsVInst) { |
| 1297 Str << getPredicate() << getWidthString(Ty); |
| 1298 } else { |
| 1299 Str << getWidthString(Ty) << getPredicate(); |
| 1300 } |
| 1301 Str << VecEltWidthString << "\t"; |
1278 getSrc(0)->emit(Func); | 1302 getSrc(0)->emit(Func); |
1279 Str << ", "; | 1303 Str << ", "; |
1280 getSrc(1)->emit(Func); | 1304 getSrc(1)->emit(Func); |
1281 } | 1305 } |
1282 | 1306 |
1283 void InstARM32Str::emitIAS(const Cfg *Func) const { | 1307 void InstARM32Str::emitIAS(const Cfg *Func) const { |
1284 assert(getSrcSize() == 2); | 1308 assert(getSrcSize() == 2); |
1285 Type Ty = getSrc(0)->getType(); | 1309 Type Ty = getSrc(0)->getType(); |
1286 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 1310 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
1287 if (isVectorType(Ty) || isScalarFloatingType(Ty)) | 1311 if (isVectorType(Ty) || isScalarFloatingType(Ty)) |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1670 template class InstARM32UnaryopGPR<InstARM32::Uxt, true>; | 1694 template class InstARM32UnaryopGPR<InstARM32::Uxt, true>; |
1671 template class InstARM32UnaryopFP<InstARM32::Vsqrt>; | 1695 template class InstARM32UnaryopFP<InstARM32::Vsqrt>; |
1672 | 1696 |
1673 template class InstARM32FourAddrGPR<InstARM32::Mla>; | 1697 template class InstARM32FourAddrGPR<InstARM32::Mla>; |
1674 template class InstARM32FourAddrGPR<InstARM32::Mls>; | 1698 template class InstARM32FourAddrGPR<InstARM32::Mls>; |
1675 | 1699 |
1676 template class InstARM32CmpLike<InstARM32::Cmp>; | 1700 template class InstARM32CmpLike<InstARM32::Cmp>; |
1677 template class InstARM32CmpLike<InstARM32::Tst>; | 1701 template class InstARM32CmpLike<InstARM32::Tst>; |
1678 | 1702 |
1679 } // end of namespace Ice | 1703 } // end of namespace Ice |
OLD | NEW |