Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |