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 |