| 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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 CondARM32::Cond Opposite; | 58 CondARM32::Cond Opposite; |
| 59 const char *EmitString; | 59 const char *EmitString; |
| 60 } InstARM32CondAttributes[] = { | 60 } InstARM32CondAttributes[] = { |
| 61 #define X(tag, encode, opp, emit) \ | 61 #define X(tag, encode, opp, emit) \ |
| 62 { CondARM32::opp, emit } \ | 62 { CondARM32::opp, emit } \ |
| 63 , | 63 , |
| 64 ICEINSTARM32COND_TABLE | 64 ICEINSTARM32COND_TABLE |
| 65 #undef X | 65 #undef X |
| 66 }; | 66 }; |
| 67 | 67 |
| 68 size_t getVecElmtBitsize(Type Ty) { |
| 69 return typeWidthInBytes(typeElementType(Ty)) * CHAR_BIT; |
| 70 } |
| 71 |
| 68 } // end of anonymous namespace | 72 } // end of anonymous namespace |
| 69 | 73 |
| 70 const char *InstARM32::getWidthString(Type Ty) { | 74 const char *InstARM32::getWidthString(Type Ty) { |
| 71 return TypeARM32Attributes[Ty].WidthString; | 75 return TypeARM32Attributes[Ty].WidthString; |
| 72 } | 76 } |
| 73 | 77 |
| 74 const char *InstARM32::getVecWidthString(Type Ty) { | 78 const char *InstARM32::getVecWidthString(Type Ty) { |
| 75 return TypeARM32Attributes[Ty].VecWidthString; | 79 return TypeARM32Attributes[Ty].VecWidthString; |
| 76 } | 80 } |
| 77 | 81 |
| (...skipping 1478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1556 return; | 1560 return; |
| 1557 Ostream &Str = Func->getContext()->getStrEmit(); | 1561 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1558 assert(getSrcSize() == 1); | 1562 assert(getSrcSize() == 1); |
| 1559 assert(getDest()->hasReg()); | 1563 assert(getDest()->hasReg()); |
| 1560 Variable *Dest = getDest(); | 1564 Variable *Dest = getDest(); |
| 1561 Type Ty = Dest->getType(); | 1565 Type Ty = Dest->getType(); |
| 1562 const bool IsVector = isVectorType(Ty); | 1566 const bool IsVector = isVectorType(Ty); |
| 1563 const bool IsScalarFloat = isScalarFloatingType(Ty); | 1567 const bool IsScalarFloat = isScalarFloatingType(Ty); |
| 1564 const char *ActualOpcode = | 1568 const char *ActualOpcode = |
| 1565 IsVector ? "vld1" : (IsScalarFloat ? "vldr" : "ldr"); | 1569 IsVector ? "vld1" : (IsScalarFloat ? "vldr" : "ldr"); |
| 1566 const char *VectorMarker = IsVector ? ".64" : ""; | |
| 1567 const char *WidthString = IsVector ? "" : getWidthString(Ty); | 1570 const char *WidthString = IsVector ? "" : getWidthString(Ty); |
| 1568 Str << "\t" << ActualOpcode; | 1571 Str << "\t" << ActualOpcode; |
| 1569 const bool IsVInst = IsVector || IsScalarFloat; | 1572 const bool IsVInst = IsVector || IsScalarFloat; |
| 1570 if (IsVInst) { | 1573 if (IsVInst) { |
| 1571 Str << getPredicate() << WidthString; | 1574 Str << getPredicate() << WidthString; |
| 1572 } else { | 1575 } else { |
| 1573 Str << WidthString << getPredicate(); | 1576 Str << WidthString << getPredicate(); |
| 1574 } | 1577 } |
| 1575 Str << VectorMarker << "\t"; | 1578 if (IsVector) |
| 1579 Str << "." << getVecElmtBitsize(Ty); |
| 1580 Str << "\t"; |
| 1576 getDest()->emit(Func); | 1581 getDest()->emit(Func); |
| 1577 Str << ", "; | 1582 Str << ", "; |
| 1578 getSrc(0)->emit(Func); | 1583 getSrc(0)->emit(Func); |
| 1579 } | 1584 } |
| 1580 | 1585 |
| 1581 template <> void InstARM32Ldr::emitIAS(const Cfg *Func) const { | 1586 template <> void InstARM32Ldr::emitIAS(const Cfg *Func) const { |
| 1582 assert(getSrcSize() == 1); | 1587 assert(getSrcSize() == 1); |
| 1588 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
| 1583 Variable *Dest = getDest(); | 1589 Variable *Dest = getDest(); |
| 1584 const Type DestTy = Dest->getType(); | 1590 const Type DestTy = Dest->getType(); |
| 1585 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 1591 switch (DestTy) { |
| 1586 if (isScalarFloatingType(DestTy)) { | 1592 default: |
| 1587 switch (DestTy) { | 1593 llvm::report_fatal_error("Ldr on unknown type: " + typeIceString(DestTy)); |
| 1588 default: | 1594 case IceType_i1: |
| 1589 // TODO(kschimpf) Does this happen? | 1595 case IceType_i8: |
| 1590 Asm->setNeedsTextFixup(); | 1596 case IceType_i16: |
| 1591 break; | 1597 case IceType_i32: |
| 1592 case IceType_f32: | 1598 case IceType_i64: |
| 1593 Asm->vldrs(Dest, getSrc(0), getPredicate(), Func->getTarget()); | |
| 1594 break; | |
| 1595 case IceType_f64: | |
| 1596 Asm->vldrd(Dest, getSrc(0), getPredicate(), Func->getTarget()); | |
| 1597 break; | |
| 1598 } | |
| 1599 } else if (isVectorType(DestTy)) | |
| 1600 // TODO(kschimpf) Handle case. | |
| 1601 Asm->setNeedsTextFixup(); | |
| 1602 else | |
| 1603 Asm->ldr(Dest, getSrc(0), getPredicate(), Func->getTarget()); | 1599 Asm->ldr(Dest, getSrc(0), getPredicate(), Func->getTarget()); |
| 1604 if (Asm->needsTextFixup()) | 1600 break; |
| 1605 emitUsingTextFixup(Func); | 1601 case IceType_f32: |
| 1602 Asm->vldrs(Dest, getSrc(0), getPredicate(), Func->getTarget()); |
| 1603 break; |
| 1604 case IceType_f64: |
| 1605 Asm->vldrd(Dest, getSrc(0), getPredicate(), Func->getTarget()); |
| 1606 break; |
| 1607 case IceType_v16i8: |
| 1608 case IceType_v8i16: |
| 1609 case IceType_v4i32: |
| 1610 case IceType_v4f32: |
| 1611 Asm->vld1qr(getVecElmtBitsize(DestTy), Dest, getSrc(0), Func->getTarget()); |
| 1612 break; |
| 1613 } |
| 1606 } | 1614 } |
| 1607 | 1615 |
| 1608 template <> void InstARM32Ldrex::emit(const Cfg *Func) const { | 1616 template <> void InstARM32Ldrex::emit(const Cfg *Func) const { |
| 1609 if (!BuildDefs::dump()) | 1617 if (!BuildDefs::dump()) |
| 1610 return; | 1618 return; |
| 1611 Ostream &Str = Func->getContext()->getStrEmit(); | 1619 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1612 assert(getSrcSize() == 1); | 1620 assert(getSrcSize() == 1); |
| 1613 assert(getDest()->hasReg()); | 1621 assert(getDest()->hasReg()); |
| 1614 Variable *Dest = getDest(); | 1622 Variable *Dest = getDest(); |
| 1615 Type DestTy = Dest->getType(); | 1623 Type DestTy = Dest->getType(); |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1891 void InstARM32Str::emit(const Cfg *Func) const { | 1899 void InstARM32Str::emit(const Cfg *Func) const { |
| 1892 if (!BuildDefs::dump()) | 1900 if (!BuildDefs::dump()) |
| 1893 return; | 1901 return; |
| 1894 Ostream &Str = Func->getContext()->getStrEmit(); | 1902 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1895 assert(getSrcSize() == 2); | 1903 assert(getSrcSize() == 2); |
| 1896 Type Ty = getSrc(0)->getType(); | 1904 Type Ty = getSrc(0)->getType(); |
| 1897 const bool IsVectorStore = isVectorType(Ty); | 1905 const bool IsVectorStore = isVectorType(Ty); |
| 1898 const bool IsScalarFloat = isScalarFloatingType(Ty); | 1906 const bool IsScalarFloat = isScalarFloatingType(Ty); |
| 1899 const char *Opcode = | 1907 const char *Opcode = |
| 1900 IsVectorStore ? "vst1" : (IsScalarFloat ? "vstr" : "str"); | 1908 IsVectorStore ? "vst1" : (IsScalarFloat ? "vstr" : "str"); |
| 1901 const char *VecEltWidthString = IsVectorStore ? ".64" : ""; | |
| 1902 Str << "\t" << Opcode; | 1909 Str << "\t" << Opcode; |
| 1903 const bool IsVInst = IsVectorStore || IsScalarFloat; | 1910 const bool IsVInst = IsVectorStore || IsScalarFloat; |
| 1904 if (IsVInst) { | 1911 if (IsVInst) { |
| 1905 Str << getPredicate() << getWidthString(Ty); | 1912 Str << getPredicate() << getWidthString(Ty); |
| 1906 } else { | 1913 } else { |
| 1907 Str << getWidthString(Ty) << getPredicate(); | 1914 Str << getWidthString(Ty) << getPredicate(); |
| 1908 } | 1915 } |
| 1909 Str << VecEltWidthString << "\t"; | 1916 if (IsVectorStore) |
| 1917 Str << "." << getVecElmtBitsize(Ty); |
| 1918 Str << "\t"; |
| 1910 getSrc(0)->emit(Func); | 1919 getSrc(0)->emit(Func); |
| 1911 Str << ", "; | 1920 Str << ", "; |
| 1912 getSrc(1)->emit(Func); | 1921 getSrc(1)->emit(Func); |
| 1913 } | 1922 } |
| 1914 | 1923 |
| 1915 void InstARM32Str::emitIAS(const Cfg *Func) const { | 1924 void InstARM32Str::emitIAS(const Cfg *Func) const { |
| 1916 assert(getSrcSize() == 2); | 1925 assert(getSrcSize() == 2); |
| 1917 Type Ty = getSrc(0)->getType(); | |
| 1918 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 1926 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
| 1919 if (isScalarFloatingType(Ty)) { | 1927 const Operand *Src0 = getSrc(0); |
| 1920 switch (Ty) { | 1928 const Operand *Src1 = getSrc(1); |
| 1921 default: | 1929 Type Ty = Src0->getType(); |
| 1922 // TODO(kschimpf) Does this happen? | 1930 switch (Ty) { |
| 1923 Asm->setNeedsTextFixup(); | 1931 default: |
| 1924 break; | 1932 llvm::report_fatal_error("Str on unknown type: " + typeIceString(Ty)); |
| 1925 case IceType_f32: | 1933 case IceType_i1: |
| 1926 Asm->vstrs(getSrc(0), getSrc(1), getPredicate(), Func->getTarget()); | 1934 case IceType_i8: |
| 1927 break; | 1935 case IceType_i16: |
| 1928 case IceType_f64: | 1936 case IceType_i32: |
| 1929 Asm->vstrd(getSrc(0), getSrc(1), getPredicate(), Func->getTarget()); | 1937 case IceType_i64: |
| 1930 break; | 1938 Asm->str(Src0, Src1, getPredicate(), Func->getTarget()); |
| 1931 } | 1939 break; |
| 1932 } else if (isVectorType(Ty)) | 1940 case IceType_f32: |
| 1933 // TODO(kschimpf) Handle case. | 1941 Asm->vstrs(Src0, Src1, getPredicate(), Func->getTarget()); |
| 1934 Asm->setNeedsTextFixup(); | 1942 break; |
| 1935 else | 1943 case IceType_f64: |
| 1936 Asm->str(getSrc(0), getSrc(1), getPredicate(), Func->getTarget()); | 1944 Asm->vstrd(Src0, Src1, getPredicate(), Func->getTarget()); |
| 1937 if (Asm->needsTextFixup()) | 1945 break; |
| 1938 emitUsingTextFixup(Func); | 1946 case IceType_v16i8: |
| 1947 case IceType_v8i16: |
| 1948 case IceType_v4i32: |
| 1949 case IceType_v4f32: |
| 1950 Asm->vst1qr(getVecElmtBitsize(Ty), Src0, Src1, Func->getTarget()); |
| 1951 break; |
| 1952 } |
| 1939 } | 1953 } |
| 1940 | 1954 |
| 1941 void InstARM32Str::dump(const Cfg *Func) const { | 1955 void InstARM32Str::dump(const Cfg *Func) const { |
| 1942 if (!BuildDefs::dump()) | 1956 if (!BuildDefs::dump()) |
| 1943 return; | 1957 return; |
| 1944 Ostream &Str = Func->getContext()->getStrDump(); | 1958 Ostream &Str = Func->getContext()->getStrDump(); |
| 1945 Type Ty = getSrc(0)->getType(); | 1959 Type Ty = getSrc(0)->getType(); |
| 1946 dumpOpcodePred(Str, "str", Ty); | 1960 dumpOpcodePred(Str, "str", Ty); |
| 1947 Str << " "; | 1961 Str << " "; |
| 1948 getSrc(1)->dump(Func); | 1962 getSrc(1)->dump(Func); |
| (...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2533 | 2547 |
| 2534 template class InstARM32FourAddrGPR<InstARM32::Mla>; | 2548 template class InstARM32FourAddrGPR<InstARM32::Mla>; |
| 2535 template class InstARM32FourAddrGPR<InstARM32::Mls>; | 2549 template class InstARM32FourAddrGPR<InstARM32::Mls>; |
| 2536 | 2550 |
| 2537 template class InstARM32CmpLike<InstARM32::Cmn>; | 2551 template class InstARM32CmpLike<InstARM32::Cmn>; |
| 2538 template class InstARM32CmpLike<InstARM32::Cmp>; | 2552 template class InstARM32CmpLike<InstARM32::Cmp>; |
| 2539 template class InstARM32CmpLike<InstARM32::Tst>; | 2553 template class InstARM32CmpLike<InstARM32::Tst>; |
| 2540 | 2554 |
| 2541 } // end of namespace ARM32 | 2555 } // end of namespace ARM32 |
| 2542 } // end of namespace Ice | 2556 } // end of namespace Ice |
| OLD | NEW |