OLD | NEW |
---|---|
1 //===- subzero/src/IceTargetLoweringX8664Traits.h - x86-64 traits -*- C++ -*-=// | 1 //===- subzero/src/IceTargetLoweringX8664Traits.h - x86-64 traits -*- 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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
54 static constexpr bool HasPopa = false; | 54 static constexpr bool HasPopa = false; |
55 static constexpr bool HasPusha = false; | 55 static constexpr bool HasPusha = false; |
56 static constexpr bool UsesX87 = false; | 56 static constexpr bool UsesX87 = false; |
57 static constexpr ::Ice::RegX8664::GPRRegister Last8BitGPR = | 57 static constexpr ::Ice::RegX8664::GPRRegister Last8BitGPR = |
58 ::Ice::RegX8664::GPRRegister::Encoded_Reg_r15d; | 58 ::Ice::RegX8664::GPRRegister::Encoded_Reg_r15d; |
59 | 59 |
60 enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 }; | 60 enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 }; |
61 | 61 |
62 using GPRRegister = ::Ice::RegX8664::GPRRegister; | 62 using GPRRegister = ::Ice::RegX8664::GPRRegister; |
63 using XmmRegister = ::Ice::RegX8664::XmmRegister; | 63 using XmmRegister = ::Ice::RegX8664::XmmRegister; |
64 using ByteRegister = ::Ice::RegX8664::ByteRegister; | |
65 | 64 |
66 using Cond = ::Ice::CondX8664; | 65 using Cond = ::Ice::CondX8664; |
67 | 66 |
68 using RegisterSet = ::Ice::RegX8664; | 67 using RegisterSet = ::Ice::RegX8664; |
69 static const GPRRegister Encoded_Reg_Accumulator = RegX8664::Encoded_Reg_eax; | 68 static const GPRRegister Encoded_Reg_Accumulator = RegX8664::Encoded_Reg_eax; |
70 static const GPRRegister Encoded_Reg_Counter = RegX8664::Encoded_Reg_ecx; | 69 static const GPRRegister Encoded_Reg_Counter = RegX8664::Encoded_Reg_ecx; |
71 static const FixupKind PcRelFixup = llvm::ELF::R_X86_64_PC32; | 70 static const FixupKind PcRelFixup = llvm::ELF::R_X86_64_PC32; |
72 static const FixupKind RelFixup = llvm::ELF::R_X86_64_32S; | 71 static const FixupKind RelFixup = llvm::ELF::R_X86_64_32S; |
73 | 72 |
74 class Operand { | 73 class Operand { |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
291 Begin, | 290 Begin, |
292 // SSE2 is the PNaCl baseline instruction set. | 291 // SSE2 is the PNaCl baseline instruction set. |
293 SSE2 = Begin, | 292 SSE2 = Begin, |
294 SSE4_1, | 293 SSE4_1, |
295 End | 294 End |
296 }; | 295 }; |
297 | 296 |
298 static const char *TargetName; | 297 static const char *TargetName; |
299 static constexpr Type WordType = IceType_i64; | 298 static constexpr Type WordType = IceType_i64; |
300 | 299 |
301 static IceString getRegName(SizeT RegNum, Type Ty) { | 300 static IceString getRegName(int32_t RegNum) { |
302 assert(RegNum < RegisterSet::Reg_NUM); | 301 static const char *const RegNames[] = { |
303 static const struct { | 302 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
304 const char *const Name8; | 303 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
305 const char *const Name16; | 304 isTrunc8Rcvr, isAhRcvr, aliases) \ |
306 const char *const Name /*32*/; | 305 name, |
307 const char *const Name64; | |
308 } RegNames[] = { | |
309 #define X(val, encode, name64, name32, name16, name8, scratch, preserved, \ | |
310 stackptr, frameptr, isInt, isFP) \ | |
311 { name8, name16, name32, name64 } \ | |
312 , | |
313 REGX8664_TABLE | 306 REGX8664_TABLE |
314 #undef X | 307 #undef X |
315 }; | 308 }; |
309 assert(RegNum >= 0); | |
310 assert(RegNum < RegisterSet::Reg_NUM); | |
311 return RegNames[RegNum]; | |
312 } | |
316 | 313 |
317 switch (Ty) { | 314 static GPRRegister getEncodedGPR(int32_t RegNum) { |
318 case IceType_i1: | 315 static const GPRRegister GPRRegs[] = { |
319 case IceType_i8: | 316 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
320 return RegNames[RegNum].Name8; | 317 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
321 case IceType_i16: | 318 isTrunc8Rcvr, isAhRcvr, aliases) \ |
322 return RegNames[RegNum].Name16; | 319 GPRRegister(isGPR ? encode : GPRRegister::Encoded_Not_GPR), |
323 case IceType_i64: | 320 REGX8664_TABLE |
324 return RegNames[RegNum].Name64; | 321 #undef X |
325 default: | 322 }; |
326 return RegNames[RegNum].Name; | 323 assert(RegNum >= 0); |
327 } | 324 assert(RegNum < RegisterSet::Reg_NUM); |
325 assert(GPRRegs[RegNum] != GPRRegister::Encoded_Not_GPR); | |
326 return GPRRegs[RegNum]; | |
328 } | 327 } |
329 | 328 |
329 static XmmRegister getEncodedXmm(int32_t RegNum) { | |
330 static const XmmRegister XmmRegs[] = { | |
331 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | |
332 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | |
333 isTrunc8Rcvr, isAhRcvr, aliases) \ | |
334 XmmRegister(isXmm ? encode : XmmRegister::Encoded_Not_Xmm), | |
335 REGX8664_TABLE | |
336 #undef X | |
337 }; | |
338 assert(RegNum >= 0); | |
339 assert(RegNum < RegisterSet::Reg_NUM); | |
340 assert(XmmRegs[RegNum] != XmmRegister::Encoded_Not_Xmm); | |
341 return XmmRegs[RegNum]; | |
342 } | |
343 | |
344 static uint32_t getEncoding(int32_t RegNum) { | |
345 static const uint32_t Encoding[] = { | |
346 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | |
347 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | |
348 isTrunc8Rcvr, isAhRcvr, aliases) \ | |
349 encode, | |
350 REGX8664_TABLE | |
351 #undef X | |
352 }; | |
353 assert(RegNum >= 0); | |
354 assert(RegNum < RegisterSet::Reg_NUM); | |
355 return Encoding[RegNum]; | |
356 } | |
357 | |
358 static inline int32_t getBaseReg(int32_t RegNum) { | |
359 static const int32_t BaseRegs[] = { | |
360 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | |
361 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | |
362 isTrunc8Rcvr, isAhRcvr, aliases) \ | |
363 RegisterSet::base, | |
364 REGX8664_TABLE | |
365 #undef X | |
366 }; | |
367 assert(RegNum >= 0); | |
368 assert(RegNum < RegisterSet::Reg_NUM); | |
369 return BaseRegs[RegNum]; | |
370 } | |
371 | |
372 static int32_t getGprForType(Type, int32_t RegNum) { return RegNum; } | |
373 | |
330 static void initRegisterSet( | 374 static void initRegisterSet( |
331 std::array<llvm::SmallBitVector, IceType_NUM> *TypeToRegisterSet, | 375 std::array<llvm::SmallBitVector, IceType_NUM> *TypeToRegisterSet, |
332 std::array<llvm::SmallBitVector, RegisterSet::Reg_NUM> *RegisterAliases, | 376 std::array<llvm::SmallBitVector, RegisterSet::Reg_NUM> *RegisterAliases, |
333 llvm::SmallBitVector *ScratchRegs) { | 377 llvm::SmallBitVector *ScratchRegs) { |
334 llvm::SmallBitVector IntegerRegisters(RegisterSet::Reg_NUM); | 378 llvm::SmallBitVector IntegerRegistersI64(RegisterSet::Reg_NUM); |
379 llvm::SmallBitVector IntegerRegistersI32(RegisterSet::Reg_NUM); | |
380 llvm::SmallBitVector IntegerRegistersI16(RegisterSet::Reg_NUM); | |
335 llvm::SmallBitVector IntegerRegistersI8(RegisterSet::Reg_NUM); | 381 llvm::SmallBitVector IntegerRegistersI8(RegisterSet::Reg_NUM); |
336 llvm::SmallBitVector FloatRegisters(RegisterSet::Reg_NUM); | 382 llvm::SmallBitVector FloatRegisters(RegisterSet::Reg_NUM); |
337 llvm::SmallBitVector VectorRegisters(RegisterSet::Reg_NUM); | 383 llvm::SmallBitVector VectorRegisters(RegisterSet::Reg_NUM); |
338 llvm::SmallBitVector InvalidRegisters(RegisterSet::Reg_NUM); | 384 llvm::SmallBitVector InvalidRegisters(RegisterSet::Reg_NUM); |
339 ScratchRegs->resize(RegisterSet::Reg_NUM); | 385 ScratchRegs->resize(RegisterSet::Reg_NUM); |
340 | 386 |
341 #define X(val, encode, name64, name32, name16, name8, scratch, preserved, \ | 387 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
342 stackptr, frameptr, isInt, isFP) \ | 388 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
343 (IntegerRegisters)[RegisterSet::val] = isInt; \ | 389 isTrunc8Rcvr, isAhRcvr, aliases) \ |
344 (IntegerRegistersI8)[RegisterSet::val] = isInt; \ | 390 (IntegerRegistersI64)[RegisterSet::val] = is64; \ |
345 (FloatRegisters)[RegisterSet::val] = isFP; \ | 391 (IntegerRegistersI32)[RegisterSet::val] = is32; \ |
346 (VectorRegisters)[RegisterSet::val] = isFP; \ | 392 (IntegerRegistersI16)[RegisterSet::val] = is16; \ |
393 (IntegerRegistersI8)[RegisterSet::val] = is8; \ | |
394 (FloatRegisters)[RegisterSet::val] = isXmm; \ | |
395 (VectorRegisters)[RegisterSet::val] = isXmm; \ | |
347 (*RegisterAliases)[RegisterSet::val].resize(RegisterSet::Reg_NUM); \ | 396 (*RegisterAliases)[RegisterSet::val].resize(RegisterSet::Reg_NUM); \ |
397 for (SizeT RegAlias : aliases) { \ | |
398 assert(!(*RegisterAliases)[RegisterSet::val][RegAlias] && \ | |
399 "Duplicate alias for " #val); \ | |
400 (*RegisterAliases)[RegisterSet::val].set(RegAlias); \ | |
401 } \ | |
348 (*RegisterAliases)[RegisterSet::val].set(RegisterSet::val); \ | 402 (*RegisterAliases)[RegisterSet::val].set(RegisterSet::val); \ |
349 (*ScratchRegs)[RegisterSet::val] = scratch; | 403 (*ScratchRegs)[RegisterSet::val] = scratch; |
350 REGX8664_TABLE; | 404 REGX8664_TABLE; |
351 #undef X | 405 #undef X |
352 | 406 |
353 (*TypeToRegisterSet)[IceType_void] = InvalidRegisters; | 407 (*TypeToRegisterSet)[IceType_void] = InvalidRegisters; |
354 (*TypeToRegisterSet)[IceType_i1] = IntegerRegistersI8; | 408 (*TypeToRegisterSet)[IceType_i1] = IntegerRegistersI8; |
355 (*TypeToRegisterSet)[IceType_i8] = IntegerRegistersI8; | 409 (*TypeToRegisterSet)[IceType_i8] = IntegerRegistersI8; |
356 (*TypeToRegisterSet)[IceType_i16] = IntegerRegisters; | 410 (*TypeToRegisterSet)[IceType_i16] = IntegerRegistersI16; |
357 (*TypeToRegisterSet)[IceType_i32] = IntegerRegisters; | 411 (*TypeToRegisterSet)[IceType_i32] = IntegerRegistersI32; |
358 (*TypeToRegisterSet)[IceType_i64] = IntegerRegisters; | 412 (*TypeToRegisterSet)[IceType_i64] = IntegerRegistersI64; |
359 (*TypeToRegisterSet)[IceType_f32] = FloatRegisters; | 413 (*TypeToRegisterSet)[IceType_f32] = FloatRegisters; |
360 (*TypeToRegisterSet)[IceType_f64] = FloatRegisters; | 414 (*TypeToRegisterSet)[IceType_f64] = FloatRegisters; |
361 (*TypeToRegisterSet)[IceType_v4i1] = VectorRegisters; | 415 (*TypeToRegisterSet)[IceType_v4i1] = VectorRegisters; |
362 (*TypeToRegisterSet)[IceType_v8i1] = VectorRegisters; | 416 (*TypeToRegisterSet)[IceType_v8i1] = VectorRegisters; |
363 (*TypeToRegisterSet)[IceType_v16i1] = VectorRegisters; | 417 (*TypeToRegisterSet)[IceType_v16i1] = VectorRegisters; |
364 (*TypeToRegisterSet)[IceType_v16i8] = VectorRegisters; | 418 (*TypeToRegisterSet)[IceType_v16i8] = VectorRegisters; |
365 (*TypeToRegisterSet)[IceType_v8i16] = VectorRegisters; | 419 (*TypeToRegisterSet)[IceType_v8i16] = VectorRegisters; |
366 (*TypeToRegisterSet)[IceType_v4i32] = VectorRegisters; | 420 (*TypeToRegisterSet)[IceType_v4i32] = VectorRegisters; |
367 (*TypeToRegisterSet)[IceType_v4f32] = VectorRegisters; | 421 (*TypeToRegisterSet)[IceType_v4f32] = VectorRegisters; |
368 } | 422 } |
369 | 423 |
370 static llvm::SmallBitVector | 424 static llvm::SmallBitVector |
371 getRegisterSet(TargetLowering::RegSetMask Include, | 425 getRegisterSet(TargetLowering::RegSetMask Include, |
372 TargetLowering::RegSetMask Exclude) { | 426 TargetLowering::RegSetMask Exclude) { |
373 llvm::SmallBitVector Registers(RegisterSet::Reg_NUM); | 427 llvm::SmallBitVector Registers(RegisterSet::Reg_NUM); |
374 | 428 |
375 #define X(val, encode, name64, name32, name16, name8, scratch, preserved, \ | 429 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
376 stackptr, frameptr, isInt, isFP) \ | 430 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
431 isTrunc8Rcvr, isAhRcvr, aliases) \ | |
377 if (scratch && (Include & ::Ice::TargetLowering::RegSet_CallerSave)) \ | 432 if (scratch && (Include & ::Ice::TargetLowering::RegSet_CallerSave)) \ |
378 Registers[RegisterSet::val] = true; \ | 433 Registers[RegisterSet::val] = true; \ |
379 if (preserved && (Include & ::Ice::TargetLowering::RegSet_CalleeSave)) \ | 434 if (preserved && (Include & ::Ice::TargetLowering::RegSet_CalleeSave)) \ |
380 Registers[RegisterSet::val] = true; \ | 435 Registers[RegisterSet::val] = true; \ |
381 if (stackptr && (Include & ::Ice::TargetLowering::RegSet_StackPointer)) \ | 436 if (stackptr && (Include & ::Ice::TargetLowering::RegSet_StackPointer)) \ |
382 Registers[RegisterSet::val] = true; \ | 437 Registers[RegisterSet::val] = true; \ |
383 if (frameptr && (Include & ::Ice::TargetLowering::RegSet_FramePointer)) \ | 438 if (frameptr && (Include & ::Ice::TargetLowering::RegSet_FramePointer)) \ |
384 Registers[RegisterSet::val] = true; \ | 439 Registers[RegisterSet::val] = true; \ |
385 if (scratch && (Exclude & ::Ice::TargetLowering::RegSet_CallerSave)) \ | 440 if (scratch && (Exclude & ::Ice::TargetLowering::RegSet_CallerSave)) \ |
386 Registers[RegisterSet::val] = false; \ | 441 Registers[RegisterSet::val] = false; \ |
(...skipping 24 matching lines...) Expand all Loading... | |
411 // for performance, not correctness. | 466 // for performance, not correctness. |
412 static const unsigned MaxEquivalenceClassSize = 8; | 467 static const unsigned MaxEquivalenceClassSize = 8; |
413 using RegisterList = llvm::SmallVector<int32_t, MaxEquivalenceClassSize>; | 468 using RegisterList = llvm::SmallVector<int32_t, MaxEquivalenceClassSize>; |
414 using EquivalenceClassMap = std::map<uint32_t, RegisterList>; | 469 using EquivalenceClassMap = std::map<uint32_t, RegisterList>; |
415 EquivalenceClassMap EquivalenceClasses; | 470 EquivalenceClassMap EquivalenceClasses; |
416 SizeT NumShuffled = 0, NumPreserved = 0; | 471 SizeT NumShuffled = 0, NumPreserved = 0; |
417 | 472 |
418 // Build up the equivalence classes of registers by looking at the register | 473 // Build up the equivalence classes of registers by looking at the register |
419 // properties as well as whether the registers should be explicitly excluded | 474 // properties as well as whether the registers should be explicitly excluded |
420 // from shuffling. | 475 // from shuffling. |
421 #define X(val, encode, name64, name32, name16, name8, scratch, preserved, \ | 476 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
422 stackptr, frameptr, isInt, isFP) \ | 477 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
478 isTrunc8Rcvr, isAhRcvr, aliases) \ | |
423 if (ExcludeRegisters[RegisterSet::val]) { \ | 479 if (ExcludeRegisters[RegisterSet::val]) { \ |
424 /* val stays the same in the resulting permutation. */ \ | 480 /* val stays the same in the resulting permutation. */ \ |
425 Permutation[RegisterSet::val] = RegisterSet::val; \ | 481 Permutation[RegisterSet::val] = RegisterSet::val; \ |
426 ++NumPreserved; \ | 482 ++NumPreserved; \ |
427 } else { \ | 483 } else { \ |
428 const uint32_t Index = (scratch << 0) | (preserved << 1) | \ | 484 const uint32_t Index = (scratch << 0) | (preserved << 1) | (is8 << 2) | \ |
Karl
2015/10/27 16:13:19
There appears to be patterns in these shifts (is8
Jim Stichnoth
2015/10/27 19:14:09
The purpose here was to combine the relevant attri
| |
429 (/*isI8=*/1 << 2) | (isInt << 3) | (isFP << 4); \ | 485 (is16 << 3) | (is32 << 4) | (is64 << 5) | \ |
486 (isXmm << 6); \ | |
430 /* val is assigned to an equivalence class based on its properties. */ \ | 487 /* val is assigned to an equivalence class based on its properties. */ \ |
431 EquivalenceClasses[Index].push_back(RegisterSet::val); \ | 488 EquivalenceClasses[Index].push_back(RegisterSet::val); \ |
432 } | 489 } |
433 REGX8664_TABLE | 490 REGX8664_TABLE |
434 #undef X | 491 #undef X |
435 | 492 |
436 // Create a random number generator for regalloc randomization. | 493 // Create a random number generator for regalloc randomization. |
437 RandomNumberGenerator RNG(Ctx->getFlags().getRandomSeed(), | 494 RandomNumberGenerator RNG(Ctx->getFlags().getRandomSeed(), |
438 RPE_RegAllocRandomization, Salt); | 495 RPE_RegAllocRandomization, Salt); |
439 RandomNumberGeneratorWrapper RNGW(RNG); | 496 RandomNumberGeneratorWrapper RNGW(RNG); |
(...skipping 16 matching lines...) Expand all Loading... | |
456 Ostream &Str = Func->getContext()->getStrDump(); | 513 Ostream &Str = Func->getContext()->getStrDump(); |
457 Str << "Register equivalence classes:\n"; | 514 Str << "Register equivalence classes:\n"; |
458 for (auto I : EquivalenceClasses) { | 515 for (auto I : EquivalenceClasses) { |
459 Str << "{"; | 516 Str << "{"; |
460 const RegisterList &List = I.second; | 517 const RegisterList &List = I.second; |
461 bool First = true; | 518 bool First = true; |
462 for (int32_t Register : List) { | 519 for (int32_t Register : List) { |
463 if (!First) | 520 if (!First) |
464 Str << " "; | 521 Str << " "; |
465 First = false; | 522 First = false; |
466 Str << getRegName(Register, IceType_i32); | 523 Str << getRegName(Register); |
467 } | 524 } |
468 Str << "}\n"; | 525 Str << "}\n"; |
469 } | 526 } |
470 } | 527 } |
471 } | 528 } |
472 | 529 |
473 /// The maximum number of arguments to pass in XMM registers | 530 /// The maximum number of arguments to pass in XMM registers |
474 static const uint32_t X86_MAX_XMM_ARGS = 8; | 531 static const uint32_t X86_MAX_XMM_ARGS = 8; |
475 /// The maximum number of arguments to pass in GPR registers | 532 /// The maximum number of arguments to pass in GPR registers |
476 static const uint32_t X86_MAX_GPR_ARGS = 6; | 533 static const uint32_t X86_MAX_GPR_ARGS = 6; |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
748 | 805 |
749 } // end of namespace X86Internal | 806 } // end of namespace X86Internal |
750 | 807 |
751 namespace X8664 { | 808 namespace X8664 { |
752 using Traits = ::Ice::X86Internal::MachineTraits<TargetX8664>; | 809 using Traits = ::Ice::X86Internal::MachineTraits<TargetX8664>; |
753 } // end of namespace X8664 | 810 } // end of namespace X8664 |
754 | 811 |
755 } // end of namespace Ice | 812 } // end of namespace Ice |
756 | 813 |
757 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8664TRAITS_H | 814 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8664TRAITS_H |
OLD | NEW |