| OLD | NEW |
| 1 //===- subzero/src/IceInstX86BaseImpl.h - Generic X86 instructions -*- C++ -*=// | 1 //===- subzero/src/IceInstX86BaseImpl.h - Generic X86 instructions -*- C++ -*=// |
| 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 /// \file | 10 /// \file |
| (...skipping 2111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2122 // acceptable type. | 2122 // acceptable type. |
| 2123 Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty, Variable::NoRegister) | 2123 Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty, Variable::NoRegister) |
| 2124 ->emit(Func); | 2124 ->emit(Func); |
| 2125 } else { | 2125 } else { |
| 2126 Src0->emit(Func); | 2126 Src0->emit(Func); |
| 2127 } | 2127 } |
| 2128 Str << ", "; | 2128 Str << ", "; |
| 2129 this->getDest()->emit(Func); | 2129 this->getDest()->emit(Func); |
| 2130 } | 2130 } |
| 2131 | 2131 |
| 2132 inline bool isIntegerConstant(const Operand *Op) { | |
| 2133 return llvm::isa<ConstantInteger32>(Op) || llvm::isa<ConstantInteger64>(Op); | |
| 2134 } | |
| 2135 | |
| 2136 template <class Machine> void InstX86Mov<Machine>::emit(const Cfg *Func) const { | 2132 template <class Machine> void InstX86Mov<Machine>::emit(const Cfg *Func) const { |
| 2137 if (!BuildDefs::dump()) | 2133 if (!BuildDefs::dump()) |
| 2138 return; | 2134 return; |
| 2139 Ostream &Str = Func->getContext()->getStrEmit(); | 2135 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2140 assert(this->getSrcSize() == 1); | 2136 assert(this->getSrcSize() == 1); |
| 2141 Operand *Src = this->getSrc(0); | 2137 Operand *Src = this->getSrc(0); |
| 2142 Type SrcTy = Src->getType(); | 2138 Type SrcTy = Src->getType(); |
| 2143 Type DestTy = this->getDest()->getType(); | 2139 Type DestTy = this->getDest()->getType(); |
| 2144 if (InstX86Base<Machine>::Traits::Is64Bit && DestTy == IceType_i64 && | 2140 if (InstX86Base<Machine>::Traits::Is64Bit && DestTy == IceType_i64 && |
| 2145 isIntegerConstant(Src)) { | 2141 llvm::isa<ConstantInteger64>(Src)) { |
| 2146 Str << "\t" | 2142 Str << "\t" |
| 2147 "movabs\t"; | 2143 "movabs" |
| 2144 "\t"; |
| 2148 } else { | 2145 } else { |
| 2149 Str << "\t" | 2146 Str << "\t" |
| 2150 "mov" << (!isScalarFloatingType(DestTy) | 2147 "mov" << (!isScalarFloatingType(DestTy) |
| 2151 ? this->getWidthString(DestTy) | 2148 ? this->getWidthString(DestTy) |
| 2152 : InstX86Base<Machine>::Traits::TypeAttributes[DestTy] | 2149 : InstX86Base<Machine>::Traits::TypeAttributes[DestTy] |
| 2153 .SdSsString) << "\t"; | 2150 .SdSsString) << "\t"; |
| 2154 } | 2151 } |
| 2155 // For an integer truncation operation, src is wider than dest. In this case, | 2152 // For an integer truncation operation, src is wider than dest. In this case, |
| 2156 // we use a mov instruction whose data width matches the narrower dest. | 2153 // we use a mov instruction whose data width matches the narrower dest. |
| 2157 // TODO: This assert disallows usages such as copying a floating | 2154 // TODO: This assert disallows usages such as copying a floating |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2207 assert(Target->typeWidthInBytesOnStack(this->getDest()->getType()) == | 2204 assert(Target->typeWidthInBytesOnStack(this->getDest()->getType()) == |
| 2208 Target->typeWidthInBytesOnStack(Src->getType())); | 2205 Target->typeWidthInBytesOnStack(Src->getType())); |
| 2209 if (Dest->hasReg()) { | 2206 if (Dest->hasReg()) { |
| 2210 if (isScalarFloatingType(DestTy)) { | 2207 if (isScalarFloatingType(DestTy)) { |
| 2211 emitIASRegOpTyXMM<Machine>(Func, DestTy, Dest, Src, XmmRegEmitter); | 2208 emitIASRegOpTyXMM<Machine>(Func, DestTy, Dest, Src, XmmRegEmitter); |
| 2212 return; | 2209 return; |
| 2213 } else { | 2210 } else { |
| 2214 assert(isScalarIntegerType(DestTy)); | 2211 assert(isScalarIntegerType(DestTy)); |
| 2215 // Widen DestTy for truncation (see above note). We should only do this | 2212 // Widen DestTy for truncation (see above note). We should only do this |
| 2216 // when both Src and Dest are integer types. | 2213 // when both Src and Dest are integer types. |
| 2217 if (InstX86Base<Machine>::Traits::Is64Bit && DestTy == IceType_i64 && | 2214 if (InstX86Base<Machine>::Traits::Is64Bit && DestTy == IceType_i64) { |
| 2218 isIntegerConstant(Src)) { | |
| 2219 uint64_t Value = -1; | |
| 2220 if (const auto *C64 = llvm::dyn_cast<ConstantInteger64>(Src)) { | 2215 if (const auto *C64 = llvm::dyn_cast<ConstantInteger64>(Src)) { |
| 2221 Value = C64->getValue(); | 2216 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>() |
| 2222 } else { | 2217 ->movabs(InstX86Base<Machine>::Traits::getEncodedGPR( |
| 2223 Value = llvm::cast<ConstantInteger32>(Src)->getValue(); | 2218 Dest->getRegNum()), |
| 2219 C64->getValue()); |
| 2220 return; |
| 2224 } | 2221 } |
| 2225 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>() | |
| 2226 ->movabs( | |
| 2227 InstX86Base<Machine>::Traits::getEncodedGPR(Dest->getRegNum()), | |
| 2228 Value); | |
| 2229 return; | |
| 2230 } | 2222 } |
| 2231 if (isScalarIntegerType(SrcTy)) { | 2223 if (isScalarIntegerType(SrcTy)) { |
| 2232 SrcTy = DestTy; | 2224 SrcTy = DestTy; |
| 2233 } | 2225 } |
| 2234 emitIASRegOpTyGPR<Machine>(Func, DestTy, Dest, Src, GPRRegEmitter); | 2226 emitIASRegOpTyGPR<Machine>(Func, DestTy, Dest, Src, GPRRegEmitter); |
| 2235 return; | 2227 return; |
| 2236 } | 2228 } |
| 2237 } else { | 2229 } else { |
| 2238 // Dest must be Stack and Src *could* be a register. Use Src's type to | 2230 // Dest must be Stack and Src *could* be a register. Use Src's type to |
| 2239 // decide on the emitters. | 2231 // decide on the emitters. |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2405 // use the full register for Dest to avoid having an OperandSizeOverride | 2397 // use the full register for Dest to avoid having an OperandSizeOverride |
| 2406 // prefix. It also allows us to only dispatch on SrcTy. | 2398 // prefix. It also allows us to only dispatch on SrcTy. |
| 2407 Type SrcTy = Src->getType(); | 2399 Type SrcTy = Src->getType(); |
| 2408 assert(typeWidthInBytes(Dest->getType()) > 1); | 2400 assert(typeWidthInBytes(Dest->getType()) > 1); |
| 2409 assert(typeWidthInBytes(Dest->getType()) > typeWidthInBytes(SrcTy)); | 2401 assert(typeWidthInBytes(Dest->getType()) > typeWidthInBytes(SrcTy)); |
| 2410 emitIASRegOpTyGPR<Machine, false, true>(Func, SrcTy, Dest, Src, | 2402 emitIASRegOpTyGPR<Machine, false, true>(Func, SrcTy, Dest, Src, |
| 2411 this->Emitter); | 2403 this->Emitter); |
| 2412 } | 2404 } |
| 2413 | 2405 |
| 2414 template <class Machine> | 2406 template <class Machine> |
| 2407 void InstX86Movzx<Machine>::emit(const Cfg *Func) const { |
| 2408 if (!BuildDefs::dump()) |
| 2409 return; |
| 2410 if (InstX86Base<Machine>::Traits::Is64Bit) { |
| 2411 // There's no movzx %eXX, %rXX. To zero extend 32- to 64-bits, we emit a |
| 2412 // mov %eXX, %eXX. The processor will still do a movzx[bw]q. |
| 2413 assert(this->getSrcSize() == 1); |
| 2414 const Operand *Src = this->getSrc(0); |
| 2415 const Variable *Dest = this->Dest; |
| 2416 if (Src->getType() == IceType_i32 && Dest->getType() == IceType_i64) { |
| 2417 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2418 Str << "\t" |
| 2419 "mov" |
| 2420 "\t"; |
| 2421 Src->emit(Func); |
| 2422 Str << ", "; |
| 2423 Dest->asType(IceType_i32, InstX86Base<Machine>::Traits::getGprForType( |
| 2424 IceType_i32, Dest->getRegNum())) |
| 2425 ->emit(Func); |
| 2426 Str << " /* movzx */"; |
| 2427 return; |
| 2428 } |
| 2429 } |
| 2430 InstX86BaseUnaryopGPR<Machine, InstX86Base<Machine>::Movzx>::emit(Func); |
| 2431 } |
| 2432 |
| 2433 template <class Machine> |
| 2415 void InstX86Movzx<Machine>::emitIAS(const Cfg *Func) const { | 2434 void InstX86Movzx<Machine>::emitIAS(const Cfg *Func) const { |
| 2416 assert(this->getSrcSize() == 1); | 2435 assert(this->getSrcSize() == 1); |
| 2417 const Variable *Dest = this->getDest(); | 2436 const Variable *Dest = this->getDest(); |
| 2418 const Operand *Src = this->getSrc(0); | 2437 const Operand *Src = this->getSrc(0); |
| 2419 Type SrcTy = Src->getType(); | 2438 Type SrcTy = Src->getType(); |
| 2420 assert(typeWidthInBytes(Dest->getType()) > 1); | 2439 assert(typeWidthInBytes(Dest->getType()) > 1); |
| 2421 assert(typeWidthInBytes(Dest->getType()) > typeWidthInBytes(SrcTy)); | 2440 assert(typeWidthInBytes(Dest->getType()) > typeWidthInBytes(SrcTy)); |
| 2422 emitIASRegOpTyGPR<Machine, false, true>(Func, SrcTy, Dest, Src, | 2441 emitIASRegOpTyGPR<Machine, false, true>(Func, SrcTy, Dest, Src, |
| 2423 this->Emitter); | 2442 this->Emitter); |
| 2424 } | 2443 } |
| (...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3034 return; | 3053 return; |
| 3035 Ostream &Str = Func->getContext()->getStrDump(); | 3054 Ostream &Str = Func->getContext()->getStrDump(); |
| 3036 Str << "IACA_END"; | 3055 Str << "IACA_END"; |
| 3037 } | 3056 } |
| 3038 | 3057 |
| 3039 } // end of namespace X86Internal | 3058 } // end of namespace X86Internal |
| 3040 | 3059 |
| 3041 } // end of namespace Ice | 3060 } // end of namespace Ice |
| 3042 | 3061 |
| 3043 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H | 3062 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H |
| OLD | NEW |