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 |