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