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

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: 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/assembler_ia32.h » ('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,
1835 RegX8632::getEncodedXmm(Dest->getRegNum()),
1835 RegX8632::getEncodedXmm(Src->getRegNum())); 1836 RegX8632::getEncodedXmm(Src->getRegNum()));
1836 Ostream &Str = Func->getContext()->getStrEmit(); 1837 Ostream &Str = Func->getContext()->getStrEmit();
1837 emitIASBytes(Str, Asm, StartPosition); 1838 emitIASBytes(Str, Asm, StartPosition);
1838 } 1839 }
1839 1840
1840 void InstX8632Movsx::emit(const Cfg *Func) const { 1841 void InstX8632Movsx::emit(const Cfg *Func) const {
1841 Ostream &Str = Func->getContext()->getStrEmit(); 1842 Ostream &Str = Func->getContext()->getStrEmit();
1842 assert(getSrcSize() == 1); 1843 assert(getSrcSize() == 1);
1843 Str << "\tmovsx\t"; 1844 Str << "\tmovsx\t";
1844 getDest()->emit(Func); 1845 getDest()->emit(Func);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1911 Str << "\n"; 1912 Str << "\n";
1912 Str << "\tfld\t" << TypeX8632Attributes[Ty].WidthString << " [esp]\n"; 1913 Str << "\tfld\t" << TypeX8632Attributes[Ty].WidthString << " [esp]\n";
1913 Str << "\tadd\tesp, " << Width << "\n"; 1914 Str << "\tadd\tesp, " << Width << "\n";
1914 return; 1915 return;
1915 } 1916 }
1916 Str << "\tfld\t"; 1917 Str << "\tfld\t";
1917 getSrc(0)->emit(Func); 1918 getSrc(0)->emit(Func);
1918 Str << "\n"; 1919 Str << "\n";
1919 } 1920 }
1920 1921
1922 void InstX8632Fld::emitIAS(const Cfg *Func) const {
1923 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1924 intptr_t StartPosition = Asm->GetPosition();
1925 assert(getSrcSize() == 1);
1926 const Operand *Src = getSrc(0);
1927 Type Ty = Src->getType();
1928 if (const auto Var = llvm::dyn_cast<Variable>(Src)) {
1929 if (Var->hasReg()) {
1930 // This is a physical xmm register, so we need to spill it to a
1931 // temporary stack slot.
1932 x86::Immediate Width(typeWidthInBytes(Ty));
1933 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width);
1934 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0);
1935 Asm->movss(Ty, StackSlot, RegX8632::getEncodedXmm(Var->getRegNum()));
1936 Asm->fld(Ty, StackSlot);
1937 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width);
1938 } else {
1939 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
1940 ->stackVarToAsmOperand(Var));
1941 Asm->fld(Ty, StackAddr);
1942 }
1943 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) {
1944 Asm->fld(Ty, Mem->toAsmAddress(Asm));
1945 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) {
1946 Asm->fld(Ty, x86::Address::ofConstPool(Func->getContext(), Asm, Imm));
1947 } else {
1948 llvm_unreachable("Unexpected operand type");
1949 }
1950 Ostream &Str = Func->getContext()->getStrEmit();
1951 emitIASBytes(Str, Asm, StartPosition);
1952 }
1953
1921 void InstX8632Fld::dump(const Cfg *Func) const { 1954 void InstX8632Fld::dump(const Cfg *Func) const {
1922 Ostream &Str = Func->getContext()->getStrDump(); 1955 Ostream &Str = Func->getContext()->getStrDump();
1923 Str << "fld." << getSrc(0)->getType() << " "; 1956 Str << "fld." << getSrc(0)->getType() << " ";
1924 dumpSources(Func); 1957 dumpSources(Func);
1925 } 1958 }
1926 1959
1927 void InstX8632Fstp::emit(const Cfg *Func) const { 1960 void InstX8632Fstp::emit(const Cfg *Func) const {
1928 Ostream &Str = Func->getContext()->getStrEmit(); 1961 Ostream &Str = Func->getContext()->getStrEmit();
1929 assert(getSrcSize() == 0); 1962 assert(getSrcSize() == 0);
1930 if (getDest() == NULL) {
Jim Stichnoth 2014/10/08 19:09:41 I think "fstp st(0)" might possibly be used in the
jvoung (off chromium) 2014/10/08 20:51:47 Okay, so the benefit of that is it can avoid alloc
Jim Stichnoth 2014/10/08 21:10:28 Yes, thanks!
1931 Str << "\tfstp\tst(0)\n";
1932 return;
1933 }
1934 if (!getDest()->hasReg()) { 1963 if (!getDest()->hasReg()) {
1935 Str << "\tfstp\t"; 1964 Str << "\tfstp\t";
1936 getDest()->emit(Func); 1965 getDest()->emit(Func);
1937 Str << "\n"; 1966 Str << "\n";
1938 return; 1967 return;
1939 } 1968 }
1940 // Dest is a physical (xmm) register, so st(0) needs to go through 1969 // Dest is a physical (xmm) register, so st(0) needs to go through
1941 // memory. Hack this by creating a temporary stack slot, spilling 1970 // memory. Hack this by creating a temporary stack slot, spilling
1942 // st(0) there, loading it into the xmm register, and deallocating 1971 // st(0) there, loading it into the xmm register, and deallocating
1943 // the stack slot. 1972 // the stack slot.
1944 Type Ty = getDest()->getType(); 1973 Type Ty = getDest()->getType();
1945 size_t Width = typeWidthInBytes(Ty); 1974 size_t Width = typeWidthInBytes(Ty);
1946 Str << "\tsub\tesp, " << Width << "\n"; 1975 Str << "\tsub\tesp, " << Width << "\n";
1947 Str << "\tfstp\t" << TypeX8632Attributes[Ty].WidthString << " [esp]\n"; 1976 Str << "\tfstp\t" << TypeX8632Attributes[Ty].WidthString << " [esp]\n";
1948 Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t"; 1977 Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t";
1949 getDest()->emit(Func); 1978 getDest()->emit(Func);
1950 Str << ", " << TypeX8632Attributes[Ty].WidthString << " [esp]\n"; 1979 Str << ", " << TypeX8632Attributes[Ty].WidthString << " [esp]\n";
1951 Str << "\tadd\tesp, " << Width << "\n"; 1980 Str << "\tadd\tesp, " << Width << "\n";
1952 } 1981 }
1953 1982
1983 void InstX8632Fstp::emitIAS(const Cfg *Func) const {
1984 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1985 intptr_t StartPosition = Asm->GetPosition();
1986 assert(getSrcSize() == 0);
1987 const Variable *Dest = getDest();
1988 Type Ty = Dest->getType();
1989 if (!Dest->hasReg()) {
1990 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
1991 ->stackVarToAsmOperand(Dest));
1992 Asm->fstp(Ty, StackAddr);
1993 } else {
1994 // Dest is a physical (xmm) register, so st(0) needs to go through
1995 // memory. Hack this by creating a temporary stack slot, spilling
1996 // st(0) there, loading it into the xmm register, and deallocating
1997 // the stack slot.
1998 x86::Immediate Width(typeWidthInBytes(Ty));
1999 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width);
2000 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0);
2001 Asm->fstp(Ty, StackSlot);
2002 Asm->movss(Ty, RegX8632::getEncodedXmm(Dest->getRegNum()), StackSlot);
2003 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width);
2004 }
2005 Ostream &Str = Func->getContext()->getStrEmit();
2006 emitIASBytes(Str, Asm, StartPosition);
2007 }
2008
1954 void InstX8632Fstp::dump(const Cfg *Func) const { 2009 void InstX8632Fstp::dump(const Cfg *Func) const {
1955 Ostream &Str = Func->getContext()->getStrDump(); 2010 Ostream &Str = Func->getContext()->getStrDump();
1956 dumpDest(Func); 2011 dumpDest(Func);
1957 Str << " = fstp." << getDest()->getType() << ", st(0)"; 2012 Str << " = fstp." << getDest()->getType() << ", st(0)";
1958 Str << "\n"; 2013 Str << "\n";
1959 } 2014 }
1960 2015
1961 template <> void InstX8632Pcmpeq::emit(const Cfg *Func) const { 2016 template <> void InstX8632Pcmpeq::emit(const Cfg *Func) const {
1962 char buf[30]; 2017 char buf[30];
1963 snprintf(buf, llvm::array_lengthof(buf), "pcmpeq%s", 2018 snprintf(buf, llvm::array_lengthof(buf), "pcmpeq%s",
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
2378 } 2433 }
2379 Str << "("; 2434 Str << "(";
2380 if (Func) 2435 if (Func)
2381 Var->dump(Func); 2436 Var->dump(Func);
2382 else 2437 else
2383 Var->dump(Str); 2438 Var->dump(Str);
2384 Str << ")"; 2439 Str << ")";
2385 } 2440 }
2386 2441
2387 } // end of namespace Ice 2442 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceInstX8632.h ('k') | src/assembler_ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698