Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(469)

Side by Side Diff: src/IceInstARM32.cpp

Issue 1663053008: Fix vector load/stores in the ARM assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Change crosstests to use filetype=obj. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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);
Jim Stichnoth 2016/02/04 20:47:37 Maybe also "const Operand *Src1 = getSrc(1);" for
Karl 2016/02/04 21:55:22 Done.
1920 switch (Ty) { 1928 Type Ty = Src0->getType();
1921 default: 1929 switch (Ty) {
1922 // TODO(kschimpf) Does this happen? 1930 default:
1923 Asm->setNeedsTextFixup(); 1931 llvm::report_fatal_error("Str on unknown type: " + typeIceString(Ty));
1924 break; 1932 case IceType_i1:
1925 case IceType_f32: 1933 case IceType_i8:
1926 Asm->vstrs(getSrc(0), getSrc(1), getPredicate(), Func->getTarget()); 1934 case IceType_i16:
1927 break; 1935 case IceType_i32:
1928 case IceType_f64: 1936 case IceType_i64:
1929 Asm->vstrd(getSrc(0), getSrc(1), getPredicate(), Func->getTarget()); 1937 Asm->str(Src0, getSrc(1), getPredicate(), Func->getTarget());
1930 break; 1938 break;
1931 } 1939 case IceType_f32:
1932 } else if (isVectorType(Ty)) 1940 Asm->vstrs(Src0, getSrc(1), getPredicate(), Func->getTarget());
1933 // TODO(kschimpf) Handle case. 1941 break;
1934 Asm->setNeedsTextFixup(); 1942 case IceType_f64:
1935 else 1943 Asm->vstrd(Src0, getSrc(1), getPredicate(), Func->getTarget());
1936 Asm->str(getSrc(0), getSrc(1), getPredicate(), Func->getTarget()); 1944 break;
1937 if (Asm->needsTextFixup()) 1945 case IceType_v16i8:
1938 emitUsingTextFixup(Func); 1946 case IceType_v8i16:
1947 case IceType_v4i32:
1948 case IceType_v4f32:
1949 Asm->vst1qr(getVecElmtBitsize(Ty), Src0, getSrc(1), Func->getTarget());
1950 break;
1951 }
1939 } 1952 }
1940 1953
1941 void InstARM32Str::dump(const Cfg *Func) const { 1954 void InstARM32Str::dump(const Cfg *Func) const {
1942 if (!BuildDefs::dump()) 1955 if (!BuildDefs::dump())
1943 return; 1956 return;
1944 Ostream &Str = Func->getContext()->getStrDump(); 1957 Ostream &Str = Func->getContext()->getStrDump();
1945 Type Ty = getSrc(0)->getType(); 1958 Type Ty = getSrc(0)->getType();
1946 dumpOpcodePred(Str, "str", Ty); 1959 dumpOpcodePred(Str, "str", Ty);
1947 Str << " "; 1960 Str << " ";
1948 getSrc(1)->dump(Func); 1961 getSrc(1)->dump(Func);
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after
2533 2546
2534 template class InstARM32FourAddrGPR<InstARM32::Mla>; 2547 template class InstARM32FourAddrGPR<InstARM32::Mla>;
2535 template class InstARM32FourAddrGPR<InstARM32::Mls>; 2548 template class InstARM32FourAddrGPR<InstARM32::Mls>;
2536 2549
2537 template class InstARM32CmpLike<InstARM32::Cmn>; 2550 template class InstARM32CmpLike<InstARM32::Cmn>;
2538 template class InstARM32CmpLike<InstARM32::Cmp>; 2551 template class InstARM32CmpLike<InstARM32::Cmp>;
2539 template class InstARM32CmpLike<InstARM32::Tst>; 2552 template class InstARM32CmpLike<InstARM32::Tst>;
2540 2553
2541 } // end of namespace ARM32 2554 } // end of namespace ARM32
2542 } // end of namespace Ice 2555 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698