OLD | NEW |
1 //===- subzero/src/IceTargetLoweringX86BaseImpl.h - x86 lowering -*- C++ -*-==// | 1 //===- subzero/src/IceTargetLoweringX86BaseImpl.h - x86 lowering -*- 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 4043 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4054 // in x86-64, __popcountsi2 is not defined, so we cheat a bit by | 4054 // in x86-64, __popcountsi2 is not defined, so we cheat a bit by |
4055 // converting it to a 64-bit value, and using ctpop_i64. _movzx should | 4055 // converting it to a 64-bit value, and using ctpop_i64. _movzx should |
4056 // ensure we will not have any bits set on Val's upper 32 bits. | 4056 // ensure we will not have any bits set on Val's upper 32 bits. |
4057 Variable *V = makeReg(IceType_i64); | 4057 Variable *V = makeReg(IceType_i64); |
4058 _movzx(V, Val); | 4058 _movzx(V, Val); |
4059 Val = V; | 4059 Val = V; |
4060 } | 4060 } |
4061 ValTy = IceType_i64; | 4061 ValTy = IceType_i64; |
4062 } | 4062 } |
4063 | 4063 |
4064 InstCall *Call = makeHelperCall( | 4064 InstCall *Call = |
4065 ValTy == IceType_i32 ? H_call_ctpop_i32 : H_call_ctpop_i64, T, 1); | 4065 makeHelperCall(ValTy == IceType_i32 ? RuntimeHelper::H_call_ctpop_i32 |
| 4066 : RuntimeHelper::H_call_ctpop_i64, |
| 4067 T, 1); |
4066 Call->addArg(Val); | 4068 Call->addArg(Val); |
4067 lowerCall(Call); | 4069 lowerCall(Call); |
4068 // The popcount helpers always return 32-bit values, while the intrinsic's | 4070 // The popcount helpers always return 32-bit values, while the intrinsic's |
4069 // signature matches the native POPCNT instruction and fills a 64-bit reg | 4071 // signature matches the native POPCNT instruction and fills a 64-bit reg |
4070 // (in 64-bit mode). Thus, clear the upper bits of the dest just in case | 4072 // (in 64-bit mode). Thus, clear the upper bits of the dest just in case |
4071 // the user doesn't do that in the IR. If the user does that in the IR, | 4073 // the user doesn't do that in the IR. If the user does that in the IR, |
4072 // then this zero'ing instruction is dead and gets optimized out. | 4074 // then this zero'ing instruction is dead and gets optimized out. |
4073 if (!Traits::Is64Bit) { | 4075 if (!Traits::Is64Bit) { |
4074 assert(T == Dest); | 4076 assert(T == Dest); |
4075 if (Val->getType() == IceType_i64) { | 4077 if (Val->getType() == IceType_i64) { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4148 Src = legalizeToReg(Src); | 4150 Src = legalizeToReg(Src); |
4149 } | 4151 } |
4150 _pand(T, Src); | 4152 _pand(T, Src); |
4151 if (isVectorType(Ty)) | 4153 if (isVectorType(Ty)) |
4152 _movp(Dest, T); | 4154 _movp(Dest, T); |
4153 else | 4155 else |
4154 _mov(Dest, T); | 4156 _mov(Dest, T); |
4155 return; | 4157 return; |
4156 } | 4158 } |
4157 case Intrinsics::Longjmp: { | 4159 case Intrinsics::Longjmp: { |
4158 InstCall *Call = makeHelperCall(H_call_longjmp, nullptr, 2); | 4160 InstCall *Call = makeHelperCall(RuntimeHelper::H_call_longjmp, nullptr, 2); |
4159 Call->addArg(Instr->getArg(0)); | 4161 Call->addArg(Instr->getArg(0)); |
4160 Call->addArg(Instr->getArg(1)); | 4162 Call->addArg(Instr->getArg(1)); |
4161 lowerCall(Call); | 4163 lowerCall(Call); |
4162 return; | 4164 return; |
4163 } | 4165 } |
4164 case Intrinsics::Memcpy: { | 4166 case Intrinsics::Memcpy: { |
4165 lowerMemcpy(Instr->getArg(0), Instr->getArg(1), Instr->getArg(2)); | 4167 lowerMemcpy(Instr->getArg(0), Instr->getArg(1), Instr->getArg(2)); |
4166 return; | 4168 return; |
4167 } | 4169 } |
4168 case Intrinsics::Memmove: { | 4170 case Intrinsics::Memmove: { |
4169 lowerMemmove(Instr->getArg(0), Instr->getArg(1), Instr->getArg(2)); | 4171 lowerMemmove(Instr->getArg(0), Instr->getArg(1), Instr->getArg(2)); |
4170 return; | 4172 return; |
4171 } | 4173 } |
4172 case Intrinsics::Memset: { | 4174 case Intrinsics::Memset: { |
4173 lowerMemset(Instr->getArg(0), Instr->getArg(1), Instr->getArg(2)); | 4175 lowerMemset(Instr->getArg(0), Instr->getArg(1), Instr->getArg(2)); |
4174 return; | 4176 return; |
4175 } | 4177 } |
4176 case Intrinsics::NaClReadTP: { | 4178 case Intrinsics::NaClReadTP: { |
4177 if (NeedSandboxing) { | 4179 if (NeedSandboxing) { |
4178 Operand *Src = | 4180 Operand *Src = |
4179 dispatchToConcrete(&ConcreteTarget::createNaClReadTPSrcOperand); | 4181 dispatchToConcrete(&ConcreteTarget::createNaClReadTPSrcOperand); |
4180 Variable *Dest = Instr->getDest(); | 4182 Variable *Dest = Instr->getDest(); |
4181 Variable *T = nullptr; | 4183 Variable *T = nullptr; |
4182 _mov(T, Src); | 4184 _mov(T, Src); |
4183 _mov(Dest, T); | 4185 _mov(Dest, T); |
4184 } else { | 4186 } else { |
4185 InstCall *Call = makeHelperCall(H_call_read_tp, Instr->getDest(), 0); | 4187 InstCall *Call = |
| 4188 makeHelperCall(RuntimeHelper::H_call_read_tp, Instr->getDest(), 0); |
4186 lowerCall(Call); | 4189 lowerCall(Call); |
4187 } | 4190 } |
4188 return; | 4191 return; |
4189 } | 4192 } |
4190 case Intrinsics::Setjmp: { | 4193 case Intrinsics::Setjmp: { |
4191 InstCall *Call = makeHelperCall(H_call_setjmp, Instr->getDest(), 1); | 4194 InstCall *Call = |
| 4195 makeHelperCall(RuntimeHelper::H_call_setjmp, Instr->getDest(), 1); |
4192 Call->addArg(Instr->getArg(0)); | 4196 Call->addArg(Instr->getArg(0)); |
4193 lowerCall(Call); | 4197 lowerCall(Call); |
4194 return; | 4198 return; |
4195 } | 4199 } |
4196 case Intrinsics::Sqrt: { | 4200 case Intrinsics::Sqrt: { |
4197 Operand *Src = legalize(Instr->getArg(0)); | 4201 Operand *Src = legalize(Instr->getArg(0)); |
4198 Variable *Dest = Instr->getDest(); | 4202 Variable *Dest = Instr->getDest(); |
4199 Variable *T = makeReg(Dest->getType()); | 4203 Variable *T = makeReg(Dest->getType()); |
4200 _sqrtss(T, Src); | 4204 _sqrtss(T, Src); |
4201 _mov(Dest, T); | 4205 _mov(Dest, T); |
(...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4755 | 4759 |
4756 // Lower the remaining bytes. Adjust to larger types in order to make use | 4760 // Lower the remaining bytes. Adjust to larger types in order to make use |
4757 // of overlaps in the copies. | 4761 // of overlaps in the copies. |
4758 Type LeftOverTy = firstTypeThatFitsSize(RemainingBytes); | 4762 Type LeftOverTy = firstTypeThatFitsSize(RemainingBytes); |
4759 Offset = CountValue - typeWidthInBytes(LeftOverTy); | 4763 Offset = CountValue - typeWidthInBytes(LeftOverTy); |
4760 copyMemory(LeftOverTy, DestBase, SrcBase, Offset); | 4764 copyMemory(LeftOverTy, DestBase, SrcBase, Offset); |
4761 return; | 4765 return; |
4762 } | 4766 } |
4763 | 4767 |
4764 // Fall back on a function call | 4768 // Fall back on a function call |
4765 InstCall *Call = makeHelperCall(H_call_memcpy, nullptr, 3); | 4769 InstCall *Call = makeHelperCall(RuntimeHelper::H_call_memcpy, nullptr, 3); |
4766 Call->addArg(Dest); | 4770 Call->addArg(Dest); |
4767 Call->addArg(Src); | 4771 Call->addArg(Src); |
4768 Call->addArg(Count); | 4772 Call->addArg(Count); |
4769 lowerCall(Call); | 4773 lowerCall(Call); |
4770 } | 4774 } |
4771 | 4775 |
4772 template <typename TraitsType> | 4776 template <typename TraitsType> |
4773 void TargetX86Base<TraitsType>::lowerMemmove(Operand *Dest, Operand *Src, | 4777 void TargetX86Base<TraitsType>::lowerMemmove(Operand *Dest, Operand *Src, |
4774 Operand *Count) { | 4778 Operand *Count) { |
4775 // There is a load and store for each chunk in the unroll | 4779 // There is a load and store for each chunk in the unroll |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4827 // Copy the data out into the destination memory | 4831 // Copy the data out into the destination memory |
4828 for (size_t i = 0; i < N; ++i) { | 4832 for (size_t i = 0; i < N; ++i) { |
4829 std::tie(Ty, Offset, Reg) = Moves[i]; | 4833 std::tie(Ty, Offset, Reg) = Moves[i]; |
4830 typedStore(Ty, Reg, DestBase, Offset); | 4834 typedStore(Ty, Reg, DestBase, Offset); |
4831 } | 4835 } |
4832 | 4836 |
4833 return; | 4837 return; |
4834 } | 4838 } |
4835 | 4839 |
4836 // Fall back on a function call | 4840 // Fall back on a function call |
4837 InstCall *Call = makeHelperCall(H_call_memmove, nullptr, 3); | 4841 InstCall *Call = makeHelperCall(RuntimeHelper::H_call_memmove, nullptr, 3); |
4838 Call->addArg(Dest); | 4842 Call->addArg(Dest); |
4839 Call->addArg(Src); | 4843 Call->addArg(Src); |
4840 Call->addArg(Count); | 4844 Call->addArg(Count); |
4841 lowerCall(Call); | 4845 lowerCall(Call); |
4842 } | 4846 } |
4843 | 4847 |
4844 template <typename TraitsType> | 4848 template <typename TraitsType> |
4845 void TargetX86Base<TraitsType>::lowerMemset(Operand *Dest, Operand *Val, | 4849 void TargetX86Base<TraitsType>::lowerMemset(Operand *Dest, Operand *Val, |
4846 Operand *Count) { | 4850 Operand *Count) { |
4847 constexpr uint32_t BytesPerStorep = 16; | 4851 constexpr uint32_t BytesPerStorep = 16; |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4936 // extended to a stack slot size because the PNaCl ABI requires arguments to | 4940 // extended to a stack slot size because the PNaCl ABI requires arguments to |
4937 // be at least 32 bits wide. | 4941 // be at least 32 bits wide. |
4938 Operand *ValExt; | 4942 Operand *ValExt; |
4939 if (IsValConst) { | 4943 if (IsValConst) { |
4940 ValExt = Ctx->getConstantInt(stackSlotType(), ValValue); | 4944 ValExt = Ctx->getConstantInt(stackSlotType(), ValValue); |
4941 } else { | 4945 } else { |
4942 Variable *ValExtVar = Func->makeVariable(stackSlotType()); | 4946 Variable *ValExtVar = Func->makeVariable(stackSlotType()); |
4943 lowerCast(InstCast::create(Func, InstCast::Zext, ValExtVar, Val)); | 4947 lowerCast(InstCast::create(Func, InstCast::Zext, ValExtVar, Val)); |
4944 ValExt = ValExtVar; | 4948 ValExt = ValExtVar; |
4945 } | 4949 } |
4946 InstCall *Call = makeHelperCall(H_call_memset, nullptr, 3); | 4950 InstCall *Call = makeHelperCall(RuntimeHelper::H_call_memset, nullptr, 3); |
4947 Call->addArg(Dest); | 4951 Call->addArg(Dest); |
4948 Call->addArg(ValExt); | 4952 Call->addArg(ValExt); |
4949 Call->addArg(Count); | 4953 Call->addArg(Count); |
4950 lowerCall(Call); | 4954 lowerCall(Call); |
4951 } | 4955 } |
4952 | 4956 |
4953 class AddressOptimizer { | 4957 class AddressOptimizer { |
4954 AddressOptimizer() = delete; | 4958 AddressOptimizer() = delete; |
4955 AddressOptimizer(const AddressOptimizer &) = delete; | 4959 AddressOptimizer(const AddressOptimizer &) = delete; |
4956 AddressOptimizer &operator=(const AddressOptimizer &) = delete; | 4960 AddressOptimizer &operator=(const AddressOptimizer &) = delete; |
(...skipping 1245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6202 // during phi lowering assignments | 6206 // during phi lowering assignments |
6203 BoolFlagSaver B(RandomizationPoolingPaused, true); | 6207 BoolFlagSaver B(RandomizationPoolingPaused, true); |
6204 PhiLowering::prelowerPhis32Bit<TargetX86Base<TraitsType>>( | 6208 PhiLowering::prelowerPhis32Bit<TargetX86Base<TraitsType>>( |
6205 this, Context.getNode(), Func); | 6209 this, Context.getNode(), Func); |
6206 } | 6210 } |
6207 | 6211 |
6208 template <typename TraitsType> | 6212 template <typename TraitsType> |
6209 void TargetX86Base<TraitsType>::genTargetHelperCallFor(Inst *Instr) { | 6213 void TargetX86Base<TraitsType>::genTargetHelperCallFor(Inst *Instr) { |
6210 uint32_t StackArgumentsSize = 0; | 6214 uint32_t StackArgumentsSize = 0; |
6211 if (auto *Arith = llvm::dyn_cast<InstArithmetic>(Instr)) { | 6215 if (auto *Arith = llvm::dyn_cast<InstArithmetic>(Instr)) { |
6212 const char *HelperName = nullptr; | 6216 RuntimeHelper HelperID = RuntimeHelper::H_Num; |
6213 Variable *Dest = Arith->getDest(); | 6217 Variable *Dest = Arith->getDest(); |
6214 Type DestTy = Dest->getType(); | 6218 Type DestTy = Dest->getType(); |
6215 if (!Traits::Is64Bit && DestTy == IceType_i64) { | 6219 if (!Traits::Is64Bit && DestTy == IceType_i64) { |
6216 switch (Arith->getOp()) { | 6220 switch (Arith->getOp()) { |
6217 default: | 6221 default: |
6218 return; | 6222 return; |
6219 case InstArithmetic::Udiv: | 6223 case InstArithmetic::Udiv: |
6220 HelperName = H_udiv_i64; | 6224 HelperID = RuntimeHelper::H_udiv_i64; |
6221 break; | 6225 break; |
6222 case InstArithmetic::Sdiv: | 6226 case InstArithmetic::Sdiv: |
6223 HelperName = H_sdiv_i64; | 6227 HelperID = RuntimeHelper::H_sdiv_i64; |
6224 break; | 6228 break; |
6225 case InstArithmetic::Urem: | 6229 case InstArithmetic::Urem: |
6226 HelperName = H_urem_i64; | 6230 HelperID = RuntimeHelper::H_urem_i64; |
6227 break; | 6231 break; |
6228 case InstArithmetic::Srem: | 6232 case InstArithmetic::Srem: |
6229 HelperName = H_srem_i64; | 6233 HelperID = RuntimeHelper::H_srem_i64; |
6230 break; | 6234 break; |
6231 } | 6235 } |
6232 } else if (isVectorType(DestTy)) { | 6236 } else if (isVectorType(DestTy)) { |
6233 Variable *Dest = Arith->getDest(); | 6237 Variable *Dest = Arith->getDest(); |
6234 Operand *Src0 = Arith->getSrc(0); | 6238 Operand *Src0 = Arith->getSrc(0); |
6235 Operand *Src1 = Arith->getSrc(1); | 6239 Operand *Src1 = Arith->getSrc(1); |
6236 switch (Arith->getOp()) { | 6240 switch (Arith->getOp()) { |
6237 default: | 6241 default: |
6238 return; | 6242 return; |
6239 case InstArithmetic::Mul: | 6243 case InstArithmetic::Mul: |
(...skipping 13 matching lines...) Expand all Loading... |
6253 scalarizeArithmetic(Arith->getOp(), Dest, Src0, Src1); | 6257 scalarizeArithmetic(Arith->getOp(), Dest, Src0, Src1); |
6254 Arith->setDeleted(); | 6258 Arith->setDeleted(); |
6255 return; | 6259 return; |
6256 } | 6260 } |
6257 } else { | 6261 } else { |
6258 switch (Arith->getOp()) { | 6262 switch (Arith->getOp()) { |
6259 default: | 6263 default: |
6260 return; | 6264 return; |
6261 case InstArithmetic::Frem: | 6265 case InstArithmetic::Frem: |
6262 if (isFloat32Asserting32Or64(DestTy)) | 6266 if (isFloat32Asserting32Or64(DestTy)) |
6263 HelperName = H_frem_f32; | 6267 HelperID = RuntimeHelper::H_frem_f32; |
6264 else | 6268 else |
6265 HelperName = H_frem_f64; | 6269 HelperID = RuntimeHelper::H_frem_f64; |
6266 } | 6270 } |
6267 } | 6271 } |
6268 constexpr SizeT MaxSrcs = 2; | 6272 constexpr SizeT MaxSrcs = 2; |
6269 InstCall *Call = makeHelperCall(HelperName, Dest, MaxSrcs); | 6273 InstCall *Call = makeHelperCall(HelperID, Dest, MaxSrcs); |
6270 Call->addArg(Arith->getSrc(0)); | 6274 Call->addArg(Arith->getSrc(0)); |
6271 Call->addArg(Arith->getSrc(1)); | 6275 Call->addArg(Arith->getSrc(1)); |
6272 StackArgumentsSize = getCallStackArgumentsSizeBytes(Call); | 6276 StackArgumentsSize = getCallStackArgumentsSizeBytes(Call); |
6273 Context.insert(Call); | 6277 Context.insert(Call); |
6274 Arith->setDeleted(); | 6278 Arith->setDeleted(); |
6275 } else if (auto *Cast = llvm::dyn_cast<InstCast>(Instr)) { | 6279 } else if (auto *Cast = llvm::dyn_cast<InstCast>(Instr)) { |
6276 InstCast::OpKind CastKind = Cast->getCastKind(); | 6280 InstCast::OpKind CastKind = Cast->getCastKind(); |
6277 Operand *Src0 = Cast->getSrc(0); | 6281 Operand *Src0 = Cast->getSrc(0); |
6278 const Type SrcType = Src0->getType(); | 6282 const Type SrcType = Src0->getType(); |
6279 Variable *Dest = Cast->getDest(); | 6283 Variable *Dest = Cast->getDest(); |
6280 const Type DestTy = Dest->getType(); | 6284 const Type DestTy = Dest->getType(); |
6281 const char *HelperName = nullptr; | 6285 RuntimeHelper HelperID = RuntimeHelper::H_Num; |
6282 Variable *CallDest = Dest; | 6286 Variable *CallDest = Dest; |
6283 switch (CastKind) { | 6287 switch (CastKind) { |
6284 default: | 6288 default: |
6285 return; | 6289 return; |
6286 case InstCast::Fptosi: | 6290 case InstCast::Fptosi: |
6287 if (!Traits::Is64Bit && DestTy == IceType_i64) { | 6291 if (!Traits::Is64Bit && DestTy == IceType_i64) { |
6288 HelperName = isFloat32Asserting32Or64(SrcType) ? H_fptosi_f32_i64 | 6292 HelperID = isFloat32Asserting32Or64(SrcType) |
6289 : H_fptosi_f64_i64; | 6293 ? RuntimeHelper::H_fptosi_f32_i64 |
| 6294 : RuntimeHelper::H_fptosi_f64_i64; |
6290 } else { | 6295 } else { |
6291 return; | 6296 return; |
6292 } | 6297 } |
6293 break; | 6298 break; |
6294 case InstCast::Fptoui: | 6299 case InstCast::Fptoui: |
6295 if (isVectorType(DestTy)) { | 6300 if (isVectorType(DestTy)) { |
6296 assert(DestTy == IceType_v4i32 && SrcType == IceType_v4f32); | 6301 assert(DestTy == IceType_v4i32 && SrcType == IceType_v4f32); |
6297 HelperName = H_fptoui_4xi32_f32; | 6302 HelperID = RuntimeHelper::H_fptoui_4xi32_f32; |
6298 } else if (DestTy == IceType_i64 || | 6303 } else if (DestTy == IceType_i64 || |
6299 (!Traits::Is64Bit && DestTy == IceType_i32)) { | 6304 (!Traits::Is64Bit && DestTy == IceType_i32)) { |
6300 if (Traits::Is64Bit) { | 6305 if (Traits::Is64Bit) { |
6301 HelperName = isFloat32Asserting32Or64(SrcType) ? H_fptoui_f32_i64 | 6306 HelperID = isFloat32Asserting32Or64(SrcType) |
6302 : H_fptoui_f64_i64; | 6307 ? RuntimeHelper::H_fptoui_f32_i64 |
| 6308 : RuntimeHelper::H_fptoui_f64_i64; |
6303 } else if (isInt32Asserting32Or64(DestTy)) { | 6309 } else if (isInt32Asserting32Or64(DestTy)) { |
6304 HelperName = isFloat32Asserting32Or64(SrcType) ? H_fptoui_f32_i32 | 6310 HelperID = isFloat32Asserting32Or64(SrcType) |
6305 : H_fptoui_f64_i32; | 6311 ? RuntimeHelper::H_fptoui_f32_i32 |
| 6312 : RuntimeHelper::H_fptoui_f64_i32; |
6306 } else { | 6313 } else { |
6307 HelperName = isFloat32Asserting32Or64(SrcType) ? H_fptoui_f32_i64 | 6314 HelperID = isFloat32Asserting32Or64(SrcType) |
6308 : H_fptoui_f64_i64; | 6315 ? RuntimeHelper::H_fptoui_f32_i64 |
| 6316 : RuntimeHelper::H_fptoui_f64_i64; |
6309 } | 6317 } |
6310 } else { | 6318 } else { |
6311 return; | 6319 return; |
6312 } | 6320 } |
6313 break; | 6321 break; |
6314 case InstCast::Sitofp: | 6322 case InstCast::Sitofp: |
6315 if (!Traits::Is64Bit && SrcType == IceType_i64) { | 6323 if (!Traits::Is64Bit && SrcType == IceType_i64) { |
6316 HelperName = isFloat32Asserting32Or64(DestTy) ? H_sitofp_i64_f32 | 6324 HelperID = isFloat32Asserting32Or64(DestTy) |
6317 : H_sitofp_i64_f64; | 6325 ? RuntimeHelper::H_sitofp_i64_f32 |
| 6326 : RuntimeHelper::H_sitofp_i64_f64; |
6318 } else { | 6327 } else { |
6319 return; | 6328 return; |
6320 } | 6329 } |
6321 break; | 6330 break; |
6322 case InstCast::Uitofp: | 6331 case InstCast::Uitofp: |
6323 if (isVectorType(SrcType)) { | 6332 if (isVectorType(SrcType)) { |
6324 assert(DestTy == IceType_v4f32 && SrcType == IceType_v4i32); | 6333 assert(DestTy == IceType_v4f32 && SrcType == IceType_v4i32); |
6325 HelperName = H_uitofp_4xi32_4xf32; | 6334 HelperID = RuntimeHelper::H_uitofp_4xi32_4xf32; |
6326 } else if (SrcType == IceType_i64 || | 6335 } else if (SrcType == IceType_i64 || |
6327 (!Traits::Is64Bit && SrcType == IceType_i32)) { | 6336 (!Traits::Is64Bit && SrcType == IceType_i32)) { |
6328 if (isInt32Asserting32Or64(SrcType)) { | 6337 if (isInt32Asserting32Or64(SrcType)) { |
6329 HelperName = isFloat32Asserting32Or64(DestTy) ? H_uitofp_i32_f32 | 6338 HelperID = isFloat32Asserting32Or64(DestTy) |
6330 : H_uitofp_i32_f64; | 6339 ? RuntimeHelper::H_uitofp_i32_f32 |
| 6340 : RuntimeHelper::H_uitofp_i32_f64; |
6331 } else { | 6341 } else { |
6332 HelperName = isFloat32Asserting32Or64(DestTy) ? H_uitofp_i64_f32 | 6342 HelperID = isFloat32Asserting32Or64(DestTy) |
6333 : H_uitofp_i64_f64; | 6343 ? RuntimeHelper::H_uitofp_i64_f32 |
| 6344 : RuntimeHelper::H_uitofp_i64_f64; |
6334 } | 6345 } |
6335 } else { | 6346 } else { |
6336 return; | 6347 return; |
6337 } | 6348 } |
6338 break; | 6349 break; |
6339 case InstCast::Bitcast: { | 6350 case InstCast::Bitcast: { |
6340 if (DestTy == Src0->getType()) | 6351 if (DestTy == Src0->getType()) |
6341 return; | 6352 return; |
6342 switch (DestTy) { | 6353 switch (DestTy) { |
6343 default: | 6354 default: |
6344 return; | 6355 return; |
6345 case IceType_i8: | 6356 case IceType_i8: |
6346 assert(Src0->getType() == IceType_v8i1); | 6357 assert(Src0->getType() == IceType_v8i1); |
6347 HelperName = H_bitcast_8xi1_i8; | 6358 HelperID = RuntimeHelper::H_bitcast_8xi1_i8; |
6348 CallDest = Func->makeVariable(IceType_i32); | 6359 CallDest = Func->makeVariable(IceType_i32); |
6349 break; | 6360 break; |
6350 case IceType_i16: | 6361 case IceType_i16: |
6351 assert(Src0->getType() == IceType_v16i1); | 6362 assert(Src0->getType() == IceType_v16i1); |
6352 HelperName = H_bitcast_16xi1_i16; | 6363 HelperID = RuntimeHelper::H_bitcast_16xi1_i16; |
6353 CallDest = Func->makeVariable(IceType_i32); | 6364 CallDest = Func->makeVariable(IceType_i32); |
6354 break; | 6365 break; |
6355 case IceType_v8i1: { | 6366 case IceType_v8i1: { |
6356 assert(Src0->getType() == IceType_i8); | 6367 assert(Src0->getType() == IceType_i8); |
6357 HelperName = H_bitcast_i8_8xi1; | 6368 HelperID = RuntimeHelper::H_bitcast_i8_8xi1; |
6358 Variable *Src0AsI32 = Func->makeVariable(stackSlotType()); | 6369 Variable *Src0AsI32 = Func->makeVariable(stackSlotType()); |
6359 // Arguments to functions are required to be at least 32 bits wide. | 6370 // Arguments to functions are required to be at least 32 bits wide. |
6360 Context.insert<InstCast>(InstCast::Zext, Src0AsI32, Src0); | 6371 Context.insert<InstCast>(InstCast::Zext, Src0AsI32, Src0); |
6361 Src0 = Src0AsI32; | 6372 Src0 = Src0AsI32; |
6362 } break; | 6373 } break; |
6363 case IceType_v16i1: { | 6374 case IceType_v16i1: { |
6364 assert(Src0->getType() == IceType_i16); | 6375 assert(Src0->getType() == IceType_i16); |
6365 HelperName = H_bitcast_i16_16xi1; | 6376 HelperID = RuntimeHelper::H_bitcast_i16_16xi1; |
6366 Variable *Src0AsI32 = Func->makeVariable(stackSlotType()); | 6377 Variable *Src0AsI32 = Func->makeVariable(stackSlotType()); |
6367 // Arguments to functions are required to be at least 32 bits wide. | 6378 // Arguments to functions are required to be at least 32 bits wide. |
6368 Context.insert<InstCast>(InstCast::Zext, Src0AsI32, Src0); | 6379 Context.insert<InstCast>(InstCast::Zext, Src0AsI32, Src0); |
6369 Src0 = Src0AsI32; | 6380 Src0 = Src0AsI32; |
6370 } break; | 6381 } break; |
6371 } | 6382 } |
6372 } break; | 6383 } break; |
6373 } | 6384 } |
6374 constexpr SizeT MaxSrcs = 1; | 6385 constexpr SizeT MaxSrcs = 1; |
6375 InstCall *Call = makeHelperCall(HelperName, CallDest, MaxSrcs); | 6386 InstCall *Call = makeHelperCall(HelperID, CallDest, MaxSrcs); |
6376 Call->addArg(Src0); | 6387 Call->addArg(Src0); |
6377 StackArgumentsSize = getCallStackArgumentsSizeBytes(Call); | 6388 StackArgumentsSize = getCallStackArgumentsSizeBytes(Call); |
6378 Context.insert(Call); | 6389 Context.insert(Call); |
6379 // The PNaCl ABI disallows i8/i16 return types, so truncate the helper call | 6390 // The PNaCl ABI disallows i8/i16 return types, so truncate the helper call |
6380 // result to the appropriate type as necessary. | 6391 // result to the appropriate type as necessary. |
6381 if (CallDest->getType() != Dest->getType()) | 6392 if (CallDest->getType() != Dest->getType()) |
6382 Context.insert<InstCast>(InstCast::Trunc, Dest, CallDest); | 6393 Context.insert<InstCast>(InstCast::Trunc, Dest, CallDest); |
6383 Cast->setDeleted(); | 6394 Cast->setDeleted(); |
6384 } else if (auto *Intrinsic = llvm::dyn_cast<InstIntrinsicCall>(Instr)) { | 6395 } else if (auto *Intrinsic = llvm::dyn_cast<InstIntrinsicCall>(Instr)) { |
6385 CfgVector<Type> ArgTypes; | 6396 CfgVector<Type> ArgTypes; |
(...skipping 1016 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7402 emitGlobal(*Var, SectionSuffix); | 7413 emitGlobal(*Var, SectionSuffix); |
7403 } | 7414 } |
7404 } | 7415 } |
7405 } break; | 7416 } break; |
7406 } | 7417 } |
7407 } | 7418 } |
7408 } // end of namespace X86NAMESPACE | 7419 } // end of namespace X86NAMESPACE |
7409 } // end of namespace Ice | 7420 } // end of namespace Ice |
7410 | 7421 |
7411 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H | 7422 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H |
OLD | NEW |