| 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 | 
|---|