OLD | NEW |
1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// | 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// |
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 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 // code eliminated as a result of the FakeKill of scratch registers after | 212 // code eliminated as a result of the FakeKill of scratch registers after |
213 // the call. | 213 // the call. |
214 Context.insert<InstFakeUse>(Reg); | 214 Context.insert<InstFakeUse>(Reg); |
215 } | 215 } |
216 // Generate the call instruction. Assign its result to a temporary with high | 216 // Generate the call instruction. Assign its result to a temporary with high |
217 // register allocation weight. | 217 // register allocation weight. |
218 // ReturnReg doubles as ReturnRegLo as necessary. | 218 // ReturnReg doubles as ReturnRegLo as necessary. |
219 Variable *ReturnReg = nullptr; | 219 Variable *ReturnReg = nullptr; |
220 Variable *ReturnRegHi = nullptr; | 220 Variable *ReturnRegHi = nullptr; |
221 if (Dest) { | 221 if (Dest) { |
222 switch (Dest->getType()) { | 222 const Type DestTy = Dest->getType(); |
| 223 switch (DestTy) { |
223 case IceType_NUM: | 224 case IceType_NUM: |
224 case IceType_void: | 225 case IceType_void: |
225 llvm::report_fatal_error("Invalid Call dest type"); | |
226 break; | |
227 case IceType_i1: | 226 case IceType_i1: |
228 case IceType_i8: | 227 case IceType_i8: |
229 case IceType_i16: | 228 case IceType_i16: |
| 229 llvm::report_fatal_error("Invalid Call dest type"); |
| 230 break; |
230 case IceType_i32: | 231 case IceType_i32: |
231 ReturnReg = makeReg(Dest->getType(), Traits::RegisterSet::Reg_eax); | 232 ReturnReg = makeReg(DestTy, Traits::RegisterSet::Reg_eax); |
232 break; | 233 break; |
233 case IceType_i64: | 234 case IceType_i64: |
234 ReturnReg = makeReg(IceType_i32, Traits::RegisterSet::Reg_eax); | 235 ReturnReg = makeReg(IceType_i32, Traits::RegisterSet::Reg_eax); |
235 ReturnRegHi = makeReg(IceType_i32, Traits::RegisterSet::Reg_edx); | 236 ReturnRegHi = makeReg(IceType_i32, Traits::RegisterSet::Reg_edx); |
236 break; | 237 break; |
237 case IceType_f32: | 238 case IceType_f32: |
238 case IceType_f64: | 239 case IceType_f64: |
239 // Leave ReturnReg==ReturnRegHi==nullptr, and capture the result with the | 240 // Leave ReturnReg==ReturnRegHi==nullptr, and capture the result with the |
240 // fstp instruction. | 241 // fstp instruction. |
241 break; | 242 break; |
242 case IceType_v4i1: | 243 case IceType_v4i1: |
243 case IceType_v8i1: | 244 case IceType_v8i1: |
244 case IceType_v16i1: | 245 case IceType_v16i1: |
245 case IceType_v16i8: | 246 case IceType_v16i8: |
246 case IceType_v8i16: | 247 case IceType_v8i16: |
247 case IceType_v4i32: | 248 case IceType_v4i32: |
248 case IceType_v4f32: | 249 case IceType_v4f32: |
249 ReturnReg = makeReg(Dest->getType(), Traits::RegisterSet::Reg_xmm0); | 250 ReturnReg = makeReg(DestTy, Traits::RegisterSet::Reg_xmm0); |
250 break; | 251 break; |
251 } | 252 } |
252 } | 253 } |
253 Operand *CallTarget = | 254 Operand *CallTarget = |
254 legalize(Instr->getCallTarget(), Legal_Reg | Legal_Imm | Legal_AddrAbs); | 255 legalize(Instr->getCallTarget(), Legal_Reg | Legal_Imm | Legal_AddrAbs); |
255 const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing(); | 256 const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing(); |
256 if (NeedSandboxing) { | 257 if (NeedSandboxing) { |
257 if (llvm::isa<Constant>(CallTarget)) { | 258 if (llvm::isa<Constant>(CallTarget)) { |
258 _bundle_lock(InstBundleLock::Opt_AlignToEnd); | 259 _bundle_lock(InstBundleLock::Opt_AlignToEnd); |
259 } else { | 260 } else { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 | 297 |
297 // Assign the result of the call to Dest. | 298 // Assign the result of the call to Dest. |
298 if (ReturnReg) { | 299 if (ReturnReg) { |
299 if (ReturnRegHi) { | 300 if (ReturnRegHi) { |
300 auto *Dest64On32 = llvm::cast<Variable64On32>(Dest); | 301 auto *Dest64On32 = llvm::cast<Variable64On32>(Dest); |
301 Variable *DestLo = Dest64On32->getLo(); | 302 Variable *DestLo = Dest64On32->getLo(); |
302 Variable *DestHi = Dest64On32->getHi(); | 303 Variable *DestHi = Dest64On32->getHi(); |
303 _mov(DestLo, ReturnReg); | 304 _mov(DestLo, ReturnReg); |
304 _mov(DestHi, ReturnRegHi); | 305 _mov(DestHi, ReturnRegHi); |
305 } else { | 306 } else { |
306 assert(Dest->getType() == IceType_i32 || Dest->getType() == IceType_i16 || | 307 const Type DestTy = Dest->getType(); |
307 Dest->getType() == IceType_i8 || Dest->getType() == IceType_i1 || | 308 assert(DestTy == IceType_i32 || DestTy == IceType_i16 || |
308 isVectorType(Dest->getType())); | 309 DestTy == IceType_i8 || DestTy == IceType_i1 || |
309 if (isVectorType(Dest->getType())) { | 310 isVectorType(DestTy)); |
| 311 if (isVectorType(DestTy)) { |
310 _movp(Dest, ReturnReg); | 312 _movp(Dest, ReturnReg); |
311 } else { | 313 } else { |
312 _mov(Dest, ReturnReg); | 314 _mov(Dest, ReturnReg); |
313 } | 315 } |
314 } | 316 } |
315 } | 317 } |
316 } | 318 } |
317 | 319 |
318 void TargetX8632::lowerArguments() { | 320 void TargetX8632::lowerArguments() { |
319 VarList &Args = Func->getArgs(); | 321 VarList &Args = Func->getArgs(); |
(...skipping 25 matching lines...) Expand all Loading... |
345 | 347 |
346 Args[I] = RegisterArg; | 348 Args[I] = RegisterArg; |
347 Context.insert<InstAssign>(Arg, RegisterArg); | 349 Context.insert<InstAssign>(Arg, RegisterArg); |
348 } | 350 } |
349 } | 351 } |
350 | 352 |
351 void TargetX8632::lowerRet(const InstRet *Inst) { | 353 void TargetX8632::lowerRet(const InstRet *Inst) { |
352 Variable *Reg = nullptr; | 354 Variable *Reg = nullptr; |
353 if (Inst->hasRetValue()) { | 355 if (Inst->hasRetValue()) { |
354 Operand *Src0 = legalize(Inst->getRetValue()); | 356 Operand *Src0 = legalize(Inst->getRetValue()); |
| 357 const Type Src0Ty = Src0->getType(); |
355 // TODO(jpp): this is not needed. | 358 // TODO(jpp): this is not needed. |
356 if (Src0->getType() == IceType_i64) { | 359 if (Src0Ty == IceType_i64) { |
357 Variable *eax = | 360 Variable *eax = |
358 legalizeToReg(loOperand(Src0), Traits::RegisterSet::Reg_eax); | 361 legalizeToReg(loOperand(Src0), Traits::RegisterSet::Reg_eax); |
359 Variable *edx = | 362 Variable *edx = |
360 legalizeToReg(hiOperand(Src0), Traits::RegisterSet::Reg_edx); | 363 legalizeToReg(hiOperand(Src0), Traits::RegisterSet::Reg_edx); |
361 Reg = eax; | 364 Reg = eax; |
362 Context.insert<InstFakeUse>(edx); | 365 Context.insert<InstFakeUse>(edx); |
363 } else if (isScalarFloatingType(Src0->getType())) { | 366 } else if (isScalarFloatingType(Src0Ty)) { |
364 _fld(Src0); | 367 _fld(Src0); |
365 } else if (isVectorType(Src0->getType())) { | 368 } else if (isVectorType(Src0Ty)) { |
366 Reg = legalizeToReg(Src0, Traits::RegisterSet::Reg_xmm0); | 369 Reg = legalizeToReg(Src0, Traits::RegisterSet::Reg_xmm0); |
367 } else { | 370 } else { |
| 371 assert(Src0Ty == IceType_i32); |
368 _mov(Reg, Src0, Traits::RegisterSet::Reg_eax); | 372 _mov(Reg, Src0, Traits::RegisterSet::Reg_eax); |
369 } | 373 } |
370 } | 374 } |
371 // Add a ret instruction even if sandboxing is enabled, because addEpilog | 375 // Add a ret instruction even if sandboxing is enabled, because addEpilog |
372 // explicitly looks for a ret instruction as a marker for where to insert the | 376 // explicitly looks for a ret instruction as a marker for where to insert the |
373 // frame removal instructions. | 377 // frame removal instructions. |
374 _ret(Reg); | 378 _ret(Reg); |
375 // Add a fake use of esp to make sure esp stays alive for the entire | 379 // Add a fake use of esp to make sure esp stays alive for the entire |
376 // function. Otherwise post-call esp adjustments get dead-code eliminated. | 380 // function. Otherwise post-call esp adjustments get dead-code eliminated. |
377 keepEspLiveAtExit(); | 381 keepEspLiveAtExit(); |
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1059 #define X(tag, sizeLog2, align, elts, elty, str) \ | 1063 #define X(tag, sizeLog2, align, elts, elty, str) \ |
1060 static_assert(_table1_##tag == _table2_##tag, \ | 1064 static_assert(_table1_##tag == _table2_##tag, \ |
1061 "Inconsistency between ICETYPEX8632_TABLE and ICETYPE_TABLE"); | 1065 "Inconsistency between ICETYPEX8632_TABLE and ICETYPE_TABLE"); |
1062 ICETYPE_TABLE | 1066 ICETYPE_TABLE |
1063 #undef X | 1067 #undef X |
1064 } // end of namespace dummy3 | 1068 } // end of namespace dummy3 |
1065 } // end of anonymous namespace | 1069 } // end of anonymous namespace |
1066 | 1070 |
1067 } // end of namespace X8632 | 1071 } // end of namespace X8632 |
1068 } // end of namespace Ice | 1072 } // end of namespace Ice |
OLD | NEW |