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, 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 Loading... |
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 Loading... |
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 |
OLD | NEW |