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