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

Side by Side Diff: src/IceInstX8632.cpp

Issue 634333002: emitIAS for fld and fstp (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: handle st(0) Created 6 years, 2 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
« no previous file with comments | « src/IceInstX8632.h ('k') | src/IceInstX8632.def » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// 1 //===- subzero/src/IceInstX8632.cpp - X86-32 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 // This file implements the InstX8632 and OperandX8632 classes, 10 // This file implements the InstX8632 and OperandX8632 classes,
(...skipping 1813 matching lines...) Expand 10 before | Expand all | Expand 10 after
1824 template <> void InstX8632MovssRegs::emitIAS(const Cfg *Func) const { 1824 template <> void InstX8632MovssRegs::emitIAS(const Cfg *Func) const {
1825 // This is Binop variant is only intended to be used for reg-reg moves 1825 // This is Binop variant is only intended to be used for reg-reg moves
1826 // where part of the Dest register is untouched. 1826 // where part of the Dest register is untouched.
1827 assert(getSrcSize() == 2); 1827 assert(getSrcSize() == 2);
1828 const Variable *Dest = getDest(); 1828 const Variable *Dest = getDest();
1829 assert(Dest == getSrc(0)); 1829 assert(Dest == getSrc(0));
1830 const Variable *Src = llvm::cast<Variable>(getSrc(1)); 1830 const Variable *Src = llvm::cast<Variable>(getSrc(1));
1831 assert(Dest->hasReg() && Src->hasReg()); 1831 assert(Dest->hasReg() && Src->hasReg());
1832 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1832 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1833 intptr_t StartPosition = Asm->GetPosition(); 1833 intptr_t StartPosition = Asm->GetPosition();
1834 Asm->movss(RegX8632::getEncodedXmm(Dest->getRegNum()), 1834 Asm->movss(IceType_f32, RegX8632::getEncodedXmm(Dest->getRegNum()),
1835 RegX8632::getEncodedXmm(Src->getRegNum())); 1835 RegX8632::getEncodedXmm(Src->getRegNum()));
1836 Ostream &Str = Func->getContext()->getStrEmit(); 1836 Ostream &Str = Func->getContext()->getStrEmit();
1837 emitIASBytes(Str, Asm, StartPosition); 1837 emitIASBytes(Str, Asm, StartPosition);
1838 } 1838 }
1839 1839
1840 void InstX8632Movsx::emit(const Cfg *Func) const { 1840 void InstX8632Movsx::emit(const Cfg *Func) const {
1841 Ostream &Str = Func->getContext()->getStrEmit(); 1841 Ostream &Str = Func->getContext()->getStrEmit();
1842 assert(getSrcSize() == 1); 1842 assert(getSrcSize() == 1);
1843 Str << "\tmovsx\t"; 1843 Str << "\tmovsx\t";
1844 getDest()->emit(Func); 1844 getDest()->emit(Func);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1911 Str << "\n"; 1911 Str << "\n";
1912 Str << "\tfld\t" << TypeX8632Attributes[Ty].WidthString << " [esp]\n"; 1912 Str << "\tfld\t" << TypeX8632Attributes[Ty].WidthString << " [esp]\n";
1913 Str << "\tadd\tesp, " << Width << "\n"; 1913 Str << "\tadd\tesp, " << Width << "\n";
1914 return; 1914 return;
1915 } 1915 }
1916 Str << "\tfld\t"; 1916 Str << "\tfld\t";
1917 getSrc(0)->emit(Func); 1917 getSrc(0)->emit(Func);
1918 Str << "\n"; 1918 Str << "\n";
1919 } 1919 }
1920 1920
1921 void InstX8632Fld::emitIAS(const Cfg *Func) const {
1922 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1923 intptr_t StartPosition = Asm->GetPosition();
1924 assert(getSrcSize() == 1);
1925 const Operand *Src = getSrc(0);
1926 Type Ty = Src->getType();
1927 if (const auto Var = llvm::dyn_cast<Variable>(Src)) {
1928 if (Var->hasReg()) {
1929 // This is a physical xmm register, so we need to spill it to a
1930 // temporary stack slot.
1931 x86::Immediate Width(typeWidthInBytes(Ty));
1932 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width);
1933 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0);
1934 Asm->movss(Ty, StackSlot, RegX8632::getEncodedXmm(Var->getRegNum()));
1935 Asm->fld(Ty, StackSlot);
1936 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width);
1937 } else {
1938 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
1939 ->stackVarToAsmOperand(Var));
1940 Asm->fld(Ty, StackAddr);
1941 }
1942 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) {
1943 Asm->fld(Ty, Mem->toAsmAddress(Asm));
1944 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) {
1945 Asm->fld(Ty, x86::Address::ofConstPool(Func->getContext(), Asm, Imm));
1946 } else {
1947 llvm_unreachable("Unexpected operand type");
1948 }
1949 Ostream &Str = Func->getContext()->getStrEmit();
1950 emitIASBytes(Str, Asm, StartPosition);
1951 }
1952
1921 void InstX8632Fld::dump(const Cfg *Func) const { 1953 void InstX8632Fld::dump(const Cfg *Func) const {
1922 Ostream &Str = Func->getContext()->getStrDump(); 1954 Ostream &Str = Func->getContext()->getStrDump();
1923 Str << "fld." << getSrc(0)->getType() << " "; 1955 Str << "fld." << getSrc(0)->getType() << " ";
1924 dumpSources(Func); 1956 dumpSources(Func);
1925 } 1957 }
1926 1958
1927 void InstX8632Fstp::emit(const Cfg *Func) const { 1959 void InstX8632Fstp::emit(const Cfg *Func) const {
1928 Ostream &Str = Func->getContext()->getStrEmit(); 1960 Ostream &Str = Func->getContext()->getStrEmit();
1929 assert(getSrcSize() == 0); 1961 assert(getSrcSize() == 0);
1962 // TODO(jvoung,stichnot): Utilize this by setting Dest to NULL to
1963 // "partially" delete the fstp if the Dest is unused.
1964 // Even if Dest is unused, the fstp should be kept for the SideEffects
1965 // of popping the stack.
1930 if (getDest() == NULL) { 1966 if (getDest() == NULL) {
1931 Str << "\tfstp\tst(0)\n"; 1967 Str << "\tfstp\tst(0)\n";
1932 return; 1968 return;
1933 } 1969 }
1934 if (!getDest()->hasReg()) { 1970 if (!getDest()->hasReg()) {
1935 Str << "\tfstp\t"; 1971 Str << "\tfstp\t";
1936 getDest()->emit(Func); 1972 getDest()->emit(Func);
1937 Str << "\n"; 1973 Str << "\n";
1938 return; 1974 return;
1939 } 1975 }
1940 // Dest is a physical (xmm) register, so st(0) needs to go through 1976 // Dest is a physical (xmm) register, so st(0) needs to go through
1941 // memory. Hack this by creating a temporary stack slot, spilling 1977 // memory. Hack this by creating a temporary stack slot, spilling
1942 // st(0) there, loading it into the xmm register, and deallocating 1978 // st(0) there, loading it into the xmm register, and deallocating
1943 // the stack slot. 1979 // the stack slot.
1944 Type Ty = getDest()->getType(); 1980 Type Ty = getDest()->getType();
1945 size_t Width = typeWidthInBytes(Ty); 1981 size_t Width = typeWidthInBytes(Ty);
1946 Str << "\tsub\tesp, " << Width << "\n"; 1982 Str << "\tsub\tesp, " << Width << "\n";
1947 Str << "\tfstp\t" << TypeX8632Attributes[Ty].WidthString << " [esp]\n"; 1983 Str << "\tfstp\t" << TypeX8632Attributes[Ty].WidthString << " [esp]\n";
1948 Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t"; 1984 Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t";
1949 getDest()->emit(Func); 1985 getDest()->emit(Func);
1950 Str << ", " << TypeX8632Attributes[Ty].WidthString << " [esp]\n"; 1986 Str << ", " << TypeX8632Attributes[Ty].WidthString << " [esp]\n";
1951 Str << "\tadd\tesp, " << Width << "\n"; 1987 Str << "\tadd\tesp, " << Width << "\n";
1952 } 1988 }
1953 1989
1990 void InstX8632Fstp::emitIAS(const Cfg *Func) const {
1991 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1992 intptr_t StartPosition = Asm->GetPosition();
1993 assert(getSrcSize() == 0);
1994 const Variable *Dest = getDest();
1995 // TODO(jvoung,stichnot): Utilize this by setting Dest to NULL to
1996 // "partially" delete the fstp if the Dest is unused.
1997 // Even if Dest is unused, the fstp should be kept for the SideEffects
1998 // of popping the stack.
1999 if (Dest == NULL) {
2000 Asm->fstp(RegX8632::getEncodedSTReg(0));
2001 Ostream &Str = Func->getContext()->getStrEmit();
2002 emitIASBytes(Str, Asm, StartPosition);
2003 return;
2004 }
2005 Type Ty = Dest->getType();
2006 if (!Dest->hasReg()) {
2007 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
2008 ->stackVarToAsmOperand(Dest));
2009 Asm->fstp(Ty, StackAddr);
2010 } else {
2011 // Dest is a physical (xmm) register, so st(0) needs to go through
2012 // memory. Hack this by creating a temporary stack slot, spilling
2013 // st(0) there, loading it into the xmm register, and deallocating
2014 // the stack slot.
2015 x86::Immediate Width(typeWidthInBytes(Ty));
2016 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width);
2017 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0);
2018 Asm->fstp(Ty, StackSlot);
2019 Asm->movss(Ty, RegX8632::getEncodedXmm(Dest->getRegNum()), StackSlot);
2020 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width);
2021 }
2022 Ostream &Str = Func->getContext()->getStrEmit();
2023 emitIASBytes(Str, Asm, StartPosition);
2024 }
2025
1954 void InstX8632Fstp::dump(const Cfg *Func) const { 2026 void InstX8632Fstp::dump(const Cfg *Func) const {
1955 Ostream &Str = Func->getContext()->getStrDump(); 2027 Ostream &Str = Func->getContext()->getStrDump();
1956 dumpDest(Func); 2028 dumpDest(Func);
1957 Str << " = fstp." << getDest()->getType() << ", st(0)"; 2029 Str << " = fstp." << getDest()->getType() << ", st(0)";
1958 Str << "\n"; 2030 Str << "\n";
1959 } 2031 }
1960 2032
1961 template <> void InstX8632Pcmpeq::emit(const Cfg *Func) const { 2033 template <> void InstX8632Pcmpeq::emit(const Cfg *Func) const {
1962 char buf[30]; 2034 char buf[30];
1963 snprintf(buf, llvm::array_lengthof(buf), "pcmpeq%s", 2035 snprintf(buf, llvm::array_lengthof(buf), "pcmpeq%s",
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
2378 } 2450 }
2379 Str << "("; 2451 Str << "(";
2380 if (Func) 2452 if (Func)
2381 Var->dump(Func); 2453 Var->dump(Func);
2382 else 2454 else
2383 Var->dump(Str); 2455 Var->dump(Str);
2384 Str << ")"; 2456 Str << ")";
2385 } 2457 }
2386 2458
2387 } // end of namespace Ice 2459 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceInstX8632.h ('k') | src/IceInstX8632.def » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698