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 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
297 SSE4_1, | 297 SSE4_1, |
298 End | 298 End |
299 }; | 299 }; |
300 | 300 |
301 static const char *TargetName; | 301 static const char *TargetName; |
302 static constexpr Type WordType = IceType_i64; | 302 static constexpr Type WordType = IceType_i64; |
303 | 303 |
304 static IceString getRegName(int32_t RegNum) { | 304 static IceString getRegName(int32_t RegNum) { |
305 static const char *const RegNames[RegisterSet::Reg_NUM] = { | 305 static const char *const RegNames[RegisterSet::Reg_NUM] = { |
306 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 306 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
307 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 307 sboxres, isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, \ |
308 isTrunc8Rcvr, isAhRcvr, aliases) \ | 308 is16To8, isTrunc8Rcvr, isAhRcvr, aliases) \ |
309 name, | 309 name, |
310 REGX8664_TABLE | 310 REGX8664_TABLE |
311 #undef X | 311 #undef X |
312 }; | 312 }; |
313 assert(RegNum >= 0); | 313 assert(RegNum >= 0); |
314 assert(RegNum < RegisterSet::Reg_NUM); | 314 assert(RegNum < RegisterSet::Reg_NUM); |
315 return RegNames[RegNum]; | 315 return RegNames[RegNum]; |
316 } | 316 } |
317 | 317 |
318 static GPRRegister getEncodedGPR(int32_t RegNum) { | 318 static GPRRegister getEncodedGPR(int32_t RegNum) { |
319 static const GPRRegister GPRRegs[RegisterSet::Reg_NUM] = { | 319 static const GPRRegister GPRRegs[RegisterSet::Reg_NUM] = { |
320 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 320 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
321 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 321 sboxres, isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, \ |
322 isTrunc8Rcvr, isAhRcvr, aliases) \ | 322 is16To8, isTrunc8Rcvr, isAhRcvr, aliases) \ |
323 GPRRegister(isGPR ? encode : GPRRegister::Encoded_Not_GPR), | 323 GPRRegister(isGPR ? encode : GPRRegister::Encoded_Not_GPR), |
324 REGX8664_TABLE | 324 REGX8664_TABLE |
325 #undef X | 325 #undef X |
326 }; | 326 }; |
327 assert(RegNum >= 0); | 327 assert(RegNum >= 0); |
328 assert(RegNum < RegisterSet::Reg_NUM); | 328 assert(RegNum < RegisterSet::Reg_NUM); |
329 assert(GPRRegs[RegNum] != GPRRegister::Encoded_Not_GPR); | 329 assert(GPRRegs[RegNum] != GPRRegister::Encoded_Not_GPR); |
330 return GPRRegs[RegNum]; | 330 return GPRRegs[RegNum]; |
331 } | 331 } |
332 | 332 |
333 static ByteRegister getEncodedByteReg(int32_t RegNum) { | 333 static ByteRegister getEncodedByteReg(int32_t RegNum) { |
334 static const ByteRegister ByteRegs[RegisterSet::Reg_NUM] = { | 334 static const ByteRegister ByteRegs[RegisterSet::Reg_NUM] = { |
335 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 335 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
336 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 336 sboxres, isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, \ |
337 isTrunc8Rcvr, isAhRcvr, aliases) \ | 337 is16To8, isTrunc8Rcvr, isAhRcvr, aliases) \ |
338 ByteRegister(is8 ? encode : ByteRegister::Encoded_Not_ByteReg), | 338 ByteRegister(is8 ? encode : ByteRegister::Encoded_Not_ByteReg), |
339 REGX8664_TABLE | 339 REGX8664_TABLE |
340 #undef X | 340 #undef X |
341 }; | 341 }; |
342 assert(RegNum >= 0); | 342 assert(RegNum >= 0); |
343 assert(RegNum < RegisterSet::Reg_NUM); | 343 assert(RegNum < RegisterSet::Reg_NUM); |
344 assert(ByteRegs[RegNum] != ByteRegister::Encoded_Not_ByteReg); | 344 assert(ByteRegs[RegNum] != ByteRegister::Encoded_Not_ByteReg); |
345 return ByteRegs[RegNum]; | 345 return ByteRegs[RegNum]; |
346 } | 346 } |
347 | 347 |
348 static XmmRegister getEncodedXmm(int32_t RegNum) { | 348 static XmmRegister getEncodedXmm(int32_t RegNum) { |
349 static const XmmRegister XmmRegs[RegisterSet::Reg_NUM] = { | 349 static const XmmRegister XmmRegs[RegisterSet::Reg_NUM] = { |
350 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 350 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
351 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 351 sboxres, isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, \ |
352 isTrunc8Rcvr, isAhRcvr, aliases) \ | 352 is16To8, isTrunc8Rcvr, isAhRcvr, aliases) \ |
353 XmmRegister(isXmm ? encode : XmmRegister::Encoded_Not_Xmm), | 353 XmmRegister(isXmm ? encode : XmmRegister::Encoded_Not_Xmm), |
354 REGX8664_TABLE | 354 REGX8664_TABLE |
355 #undef X | 355 #undef X |
356 }; | 356 }; |
357 assert(RegNum >= 0); | 357 assert(RegNum >= 0); |
358 assert(RegNum < RegisterSet::Reg_NUM); | 358 assert(RegNum < RegisterSet::Reg_NUM); |
359 assert(XmmRegs[RegNum] != XmmRegister::Encoded_Not_Xmm); | 359 assert(XmmRegs[RegNum] != XmmRegister::Encoded_Not_Xmm); |
360 return XmmRegs[RegNum]; | 360 return XmmRegs[RegNum]; |
361 } | 361 } |
362 | 362 |
363 static uint32_t getEncoding(int32_t RegNum) { | 363 static uint32_t getEncoding(int32_t RegNum) { |
364 static const uint32_t Encoding[RegisterSet::Reg_NUM] = { | 364 static const uint32_t Encoding[RegisterSet::Reg_NUM] = { |
365 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 365 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
366 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 366 sboxres, isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, \ |
367 isTrunc8Rcvr, isAhRcvr, aliases) \ | 367 is16To8, isTrunc8Rcvr, isAhRcvr, aliases) \ |
368 encode, | 368 encode, |
369 REGX8664_TABLE | 369 REGX8664_TABLE |
370 #undef X | 370 #undef X |
371 }; | 371 }; |
372 assert(RegNum >= 0); | 372 assert(RegNum >= 0); |
373 assert(RegNum < RegisterSet::Reg_NUM); | 373 assert(RegNum < RegisterSet::Reg_NUM); |
374 return Encoding[RegNum]; | 374 return Encoding[RegNum]; |
375 } | 375 } |
376 | 376 |
377 static inline int32_t getBaseReg(int32_t RegNum) { | 377 static inline int32_t getBaseReg(int32_t RegNum) { |
378 static const int32_t BaseRegs[RegisterSet::Reg_NUM] = { | 378 static const int32_t BaseRegs[RegisterSet::Reg_NUM] = { |
379 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 379 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
380 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 380 sboxres, isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, \ |
381 isTrunc8Rcvr, isAhRcvr, aliases) \ | 381 is16To8, isTrunc8Rcvr, isAhRcvr, aliases) \ |
382 RegisterSet::base, | 382 encode, |
383 REGX8664_TABLE | 383 REGX8664_TABLE |
384 #undef X | 384 #undef X |
385 }; | 385 }; |
386 assert(RegNum >= 0); | 386 assert(RegNum >= 0); |
387 assert(RegNum < RegisterSet::Reg_NUM); | 387 assert(RegNum < RegisterSet::Reg_NUM); |
388 return BaseRegs[RegNum]; | 388 return BaseRegs[RegNum]; |
389 } | 389 } |
390 | 390 |
391 private: | 391 private: |
392 static int32_t getFirstGprForType(Type Ty) { | 392 static int32_t getFirstGprForType(Type Ty) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
424 assert(RegNum != RegisterSet::Reg_bh); | 424 assert(RegNum != RegisterSet::Reg_bh); |
425 assert(RegNum != RegisterSet::Reg_ch); | 425 assert(RegNum != RegisterSet::Reg_ch); |
426 assert(RegNum != RegisterSet::Reg_dh); | 426 assert(RegNum != RegisterSet::Reg_dh); |
427 | 427 |
428 const int32_t FirstGprForType = getFirstGprForType(Ty); | 428 const int32_t FirstGprForType = getFirstGprForType(Ty); |
429 | 429 |
430 switch (RegNum) { | 430 switch (RegNum) { |
431 default: | 431 default: |
432 llvm::report_fatal_error("Unknown register."); | 432 llvm::report_fatal_error("Unknown register."); |
433 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 433 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
434 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 434 sboxres, isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, \ |
435 isTrunc8Rcvr, isAhRcvr, aliases) \ | 435 is16To8, isTrunc8Rcvr, isAhRcvr, aliases) \ |
436 case RegisterSet::val: { \ | 436 case RegisterSet::val: { \ |
437 assert(isGPR); \ | 437 if (!isGPR) \ |
438 return RegisterSet::val; \ | |
438 assert((is64) || (is32) || (is16) || (is8) || \ | 439 assert((is64) || (is32) || (is16) || (is8) || \ |
439 getBaseReg(RegisterSet::val) == RegisterSet::Reg_rsp); \ | 440 getBaseReg(RegisterSet::val) == RegisterSet::Reg_rsp || \ |
441 getBaseReg(RegisterSet::val) == RegisterSet::Reg_rbp); \ | |
440 constexpr int32_t FirstGprWithRegNumSize = \ | 442 constexpr int32_t FirstGprWithRegNumSize = \ |
441 ((is64) || RegisterSet::val == RegisterSet::Reg_rsp) \ | 443 ((is64) || RegisterSet::val == RegisterSet::Reg_rsp || \ |
444 RegisterSet::val == RegisterSet::Reg_rbp) \ | |
442 ? RegisterSet::Reg_rax \ | 445 ? RegisterSet::Reg_rax \ |
443 : (((is32) || RegisterSet::val == RegisterSet::Reg_esp) \ | 446 : (((is32) || RegisterSet::val == RegisterSet::Reg_esp || \ |
447 RegisterSet::val == RegisterSet::Reg_ebp) \ | |
444 ? RegisterSet::Reg_eax \ | 448 ? RegisterSet::Reg_eax \ |
445 : (((is16) || RegisterSet::val == RegisterSet::Reg_sp) \ | 449 : (((is16) || RegisterSet::val == RegisterSet::Reg_sp || \ |
450 RegisterSet::val == RegisterSet::Reg_bp) \ | |
446 ? RegisterSet::Reg_ax \ | 451 ? RegisterSet::Reg_ax \ |
447 : RegisterSet::Reg_al)); \ | 452 : RegisterSet::Reg_al)); \ |
448 const int32_t NewRegNum = \ | 453 const int32_t NewRegNum = \ |
449 RegNum - FirstGprWithRegNumSize + FirstGprForType; \ | 454 RegNum - FirstGprWithRegNumSize + FirstGprForType; \ |
450 assert(getBaseReg(RegNum) == getBaseReg(NewRegNum) && \ | 455 assert(getBaseReg(RegNum) == getBaseReg(NewRegNum) && \ |
451 "Error involving " #val); \ | 456 "Error involving " #val); \ |
452 return NewRegNum; \ | 457 return NewRegNum; \ |
453 } | 458 } |
454 REGX8664_TABLE | 459 REGX8664_TABLE |
455 #undef X | 460 #undef X |
456 } | 461 } |
457 } | 462 } |
458 | 463 |
459 private: | 464 private: |
460 /// SizeOf is used to obtain the size of an initializer list as a constexpr | 465 /// SizeOf is used to obtain the size of an initializer list as a constexpr |
461 /// expression. This is only needed until our C++ library is updated to | 466 /// expression. This is only needed until our C++ library is updated to |
462 /// C++ 14 -- which defines constexpr members to std::initializer_list. | 467 /// C++ 14 -- which defines constexpr members to std::initializer_list. |
463 class SizeOf { | 468 class SizeOf { |
464 SizeOf(const SizeOf &) = delete; | 469 SizeOf(const SizeOf &) = delete; |
465 SizeOf &operator=(const SizeOf &) = delete; | 470 SizeOf &operator=(const SizeOf &) = delete; |
466 | 471 |
467 public: | 472 public: |
468 constexpr SizeOf() : Size(0) {} | 473 constexpr SizeOf() : Size(0) {} |
469 template <typename... T> | 474 template <typename... T> |
470 explicit constexpr SizeOf(T...) | 475 explicit constexpr SizeOf(T...) |
471 : Size(__length<T...>::value) {} | 476 : Size(length<T...>::value) {} |
472 constexpr SizeT size() const { return Size; } | 477 constexpr SizeT size() const { return Size; } |
473 | 478 |
474 private: | 479 private: |
475 template <typename T, typename... U> struct __length { | 480 template <typename T, typename... U> struct length { |
476 static constexpr std::size_t value = 1 + __length<U...>::value; | 481 static constexpr std::size_t value = 1 + length<U...>::value; |
477 }; | 482 }; |
478 | 483 |
479 template <typename T> struct __length<T> { | 484 template <typename T> struct length<T> { |
480 static constexpr std::size_t value = 1; | 485 static constexpr std::size_t value = 1; |
481 }; | 486 }; |
482 | 487 |
483 const std::size_t Size; | 488 const std::size_t Size; |
484 }; | 489 }; |
485 | 490 |
486 public: | 491 public: |
487 static void initRegisterSet( | 492 static void initRegisterSet( |
493 const ::Ice::ClFlags &Flags, | |
488 std::array<llvm::SmallBitVector, RCX86_NUM> *TypeToRegisterSet, | 494 std::array<llvm::SmallBitVector, RCX86_NUM> *TypeToRegisterSet, |
489 std::array<llvm::SmallBitVector, RegisterSet::Reg_NUM> *RegisterAliases, | 495 std::array<llvm::SmallBitVector, RegisterSet::Reg_NUM> *RegisterAliases, |
490 llvm::SmallBitVector *ScratchRegs) { | 496 llvm::SmallBitVector *ScratchRegs) { |
491 llvm::SmallBitVector IntegerRegistersI64(RegisterSet::Reg_NUM); | 497 llvm::SmallBitVector IntegerRegistersI64(RegisterSet::Reg_NUM); |
492 llvm::SmallBitVector IntegerRegistersI32(RegisterSet::Reg_NUM); | 498 llvm::SmallBitVector IntegerRegistersI32(RegisterSet::Reg_NUM); |
493 llvm::SmallBitVector IntegerRegistersI16(RegisterSet::Reg_NUM); | 499 llvm::SmallBitVector IntegerRegistersI16(RegisterSet::Reg_NUM); |
494 llvm::SmallBitVector IntegerRegistersI8(RegisterSet::Reg_NUM); | 500 llvm::SmallBitVector IntegerRegistersI8(RegisterSet::Reg_NUM); |
495 llvm::SmallBitVector FloatRegisters(RegisterSet::Reg_NUM); | 501 llvm::SmallBitVector FloatRegisters(RegisterSet::Reg_NUM); |
496 llvm::SmallBitVector VectorRegisters(RegisterSet::Reg_NUM); | 502 llvm::SmallBitVector VectorRegisters(RegisterSet::Reg_NUM); |
497 llvm::SmallBitVector Trunc64To8Registers(RegisterSet::Reg_NUM); | 503 llvm::SmallBitVector Trunc64To8Registers(RegisterSet::Reg_NUM); |
498 llvm::SmallBitVector Trunc32To8Registers(RegisterSet::Reg_NUM); | 504 llvm::SmallBitVector Trunc32To8Registers(RegisterSet::Reg_NUM); |
499 llvm::SmallBitVector Trunc16To8Registers(RegisterSet::Reg_NUM); | 505 llvm::SmallBitVector Trunc16To8Registers(RegisterSet::Reg_NUM); |
500 llvm::SmallBitVector Trunc8RcvrRegisters(RegisterSet::Reg_NUM); | 506 llvm::SmallBitVector Trunc8RcvrRegisters(RegisterSet::Reg_NUM); |
501 llvm::SmallBitVector AhRcvrRegisters(RegisterSet::Reg_NUM); | 507 llvm::SmallBitVector AhRcvrRegisters(RegisterSet::Reg_NUM); |
502 llvm::SmallBitVector InvalidRegisters(RegisterSet::Reg_NUM); | 508 llvm::SmallBitVector InvalidRegisters(RegisterSet::Reg_NUM); |
503 ScratchRegs->resize(RegisterSet::Reg_NUM); | 509 ScratchRegs->resize(RegisterSet::Reg_NUM); |
504 | 510 |
505 static constexpr struct { | 511 static constexpr struct { |
506 uint16_t Val; | 512 uint16_t Val; |
513 unsigned IsReservedWhenSandboxing : 1; | |
507 unsigned Is64 : 1; | 514 unsigned Is64 : 1; |
508 unsigned Is32 : 1; | 515 unsigned Is32 : 1; |
509 unsigned Is16 : 1; | 516 unsigned Is16 : 1; |
510 unsigned Is8 : 1; | 517 unsigned Is8 : 1; |
511 unsigned IsXmm : 1; | 518 unsigned IsXmm : 1; |
512 unsigned Is64To8 : 1; | 519 unsigned Is64To8 : 1; |
513 unsigned Is32To8 : 1; | 520 unsigned Is32To8 : 1; |
514 unsigned Is16To8 : 1; | 521 unsigned Is16To8 : 1; |
515 unsigned IsTrunc8Rcvr : 1; | 522 unsigned IsTrunc8Rcvr : 1; |
516 unsigned IsAhRcvr : 1; | 523 unsigned IsAhRcvr : 1; |
517 unsigned Scratch : 1; | 524 unsigned Scratch : 1; |
518 #define NUM_ALIASES_BITS 2 | 525 #define NUM_ALIASES_BITS 2 |
519 SizeT NumAliases : (NUM_ALIASES_BITS + 1); | 526 SizeT NumAliases : (NUM_ALIASES_BITS + 1); |
520 uint16_t Aliases[1 << NUM_ALIASES_BITS]; | 527 uint16_t Aliases[1 << NUM_ALIASES_BITS]; |
521 #undef NUM_ALIASES_BITS | 528 #undef NUM_ALIASES_BITS |
522 } X8664RegTable[RegisterSet::Reg_NUM] = { | 529 } X8664RegTable[RegisterSet::Reg_NUM] = { |
523 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 530 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
524 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 531 sboxres, isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, \ |
525 isTrunc8Rcvr, isAhRcvr, aliases) \ | 532 is16To8, isTrunc8Rcvr, isAhRcvr, aliases) \ |
526 { \ | 533 { \ |
527 RegisterSet::val, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 534 RegisterSet::val, sboxres, is64, is32, is16, is8, isXmm, is64To8, is32To8, \ |
528 isTrunc8Rcvr, isAhRcvr, scratch, (SizeOf aliases).size(), aliases, \ | 535 is16To8, isTrunc8Rcvr, isAhRcvr, scratch, (SizeOf aliases).size(), \ |
536 aliases, \ | |
529 } \ | 537 } \ |
530 , | 538 , |
531 REGX8664_TABLE | 539 REGX8664_TABLE |
532 #undef X | 540 #undef X |
533 }; | 541 }; |
534 | 542 |
543 const bool NeedSandboxing = Flags.getUseSandboxing(); | |
535 for (SizeT ii = 0; ii < llvm::array_lengthof(X8664RegTable); ++ii) { | 544 for (SizeT ii = 0; ii < llvm::array_lengthof(X8664RegTable); ++ii) { |
536 const auto &Entry = X8664RegTable[ii]; | 545 const auto &Entry = X8664RegTable[ii]; |
546 // Even though the register is disabled for register allocation, it might | |
547 // still be used by the Target Lowering (e.g., base pointer), so the | |
548 // register talias table still needs to be defined. | |
Jim Stichnoth
2016/01/14 00:09:52
alias
John
2016/01/14 23:18:25
Done.
| |
549 (*RegisterAliases)[Entry.Val].resize(RegisterSet::Reg_NUM); | |
550 for (int J = 0; J < Entry.NumAliases; ++J) { | |
551 SizeT Alias = Entry.Aliases[J]; | |
552 assert(!(*RegisterAliases)[Entry.Val][Alias] && "Duplicate alias"); | |
553 (*RegisterAliases)[Entry.Val].set(Alias); | |
554 } | |
555 | |
556 (*RegisterAliases)[Entry.Val].set(Entry.Val); | |
557 const bool DisabledRegister = | |
558 NeedSandboxing && Entry.IsReservedWhenSandboxing; | |
559 if (DisabledRegister) { | |
560 continue; | |
561 } | |
537 (IntegerRegistersI64)[Entry.Val] = Entry.Is64; | 562 (IntegerRegistersI64)[Entry.Val] = Entry.Is64; |
538 (IntegerRegistersI32)[Entry.Val] = Entry.Is32; | 563 (IntegerRegistersI32)[Entry.Val] = Entry.Is32; |
539 (IntegerRegistersI16)[Entry.Val] = Entry.Is16; | 564 (IntegerRegistersI16)[Entry.Val] = Entry.Is16; |
540 (IntegerRegistersI8)[Entry.Val] = Entry.Is8; | 565 (IntegerRegistersI8)[Entry.Val] = Entry.Is8; |
541 (FloatRegisters)[Entry.Val] = Entry.IsXmm; | 566 (FloatRegisters)[Entry.Val] = Entry.IsXmm; |
542 (VectorRegisters)[Entry.Val] = Entry.IsXmm; | 567 (VectorRegisters)[Entry.Val] = Entry.IsXmm; |
543 (Trunc64To8Registers)[Entry.Val] = Entry.Is64To8; | 568 (Trunc64To8Registers)[Entry.Val] = Entry.Is64To8; |
544 (Trunc32To8Registers)[Entry.Val] = Entry.Is32To8; | 569 (Trunc32To8Registers)[Entry.Val] = Entry.Is32To8; |
545 (Trunc16To8Registers)[Entry.Val] = Entry.Is16To8; | 570 (Trunc16To8Registers)[Entry.Val] = Entry.Is16To8; |
546 (Trunc8RcvrRegisters)[Entry.Val] = Entry.IsTrunc8Rcvr; | 571 (Trunc8RcvrRegisters)[Entry.Val] = Entry.IsTrunc8Rcvr; |
547 (AhRcvrRegisters)[Entry.Val] = Entry.IsAhRcvr; | 572 (AhRcvrRegisters)[Entry.Val] = Entry.IsAhRcvr; |
548 (*RegisterAliases)[Entry.Val].resize(RegisterSet::Reg_NUM); | |
549 for (int J = 0; J < Entry.NumAliases; ++J) { | |
550 SizeT Alias = Entry.Aliases[J]; | |
551 assert(!(*RegisterAliases)[Entry.Val][Alias] && "Duplicate alias"); | |
552 (*RegisterAliases)[Entry.Val].set(Alias); | |
553 } | |
554 (*RegisterAliases)[Entry.Val].set(Entry.Val); | |
555 (*ScratchRegs)[Entry.Val] = Entry.Scratch; | 573 (*ScratchRegs)[Entry.Val] = Entry.Scratch; |
556 } | 574 } |
557 | 575 |
558 (*TypeToRegisterSet)[RC_void] = InvalidRegisters; | 576 (*TypeToRegisterSet)[RC_void] = InvalidRegisters; |
559 (*TypeToRegisterSet)[RC_i1] = IntegerRegistersI8; | 577 (*TypeToRegisterSet)[RC_i1] = IntegerRegistersI8; |
560 (*TypeToRegisterSet)[RC_i8] = IntegerRegistersI8; | 578 (*TypeToRegisterSet)[RC_i8] = IntegerRegistersI8; |
561 (*TypeToRegisterSet)[RC_i16] = IntegerRegistersI16; | 579 (*TypeToRegisterSet)[RC_i16] = IntegerRegistersI16; |
562 (*TypeToRegisterSet)[RC_i32] = IntegerRegistersI32; | 580 (*TypeToRegisterSet)[RC_i32] = IntegerRegistersI32; |
563 (*TypeToRegisterSet)[RC_i64] = IntegerRegistersI64; | 581 (*TypeToRegisterSet)[RC_i64] = IntegerRegistersI64; |
564 (*TypeToRegisterSet)[RC_f32] = FloatRegisters; | 582 (*TypeToRegisterSet)[RC_f32] = FloatRegisters; |
565 (*TypeToRegisterSet)[RC_f64] = FloatRegisters; | 583 (*TypeToRegisterSet)[RC_f64] = FloatRegisters; |
566 (*TypeToRegisterSet)[RC_v4i1] = VectorRegisters; | 584 (*TypeToRegisterSet)[RC_v4i1] = VectorRegisters; |
567 (*TypeToRegisterSet)[RC_v8i1] = VectorRegisters; | 585 (*TypeToRegisterSet)[RC_v8i1] = VectorRegisters; |
568 (*TypeToRegisterSet)[RC_v16i1] = VectorRegisters; | 586 (*TypeToRegisterSet)[RC_v16i1] = VectorRegisters; |
569 (*TypeToRegisterSet)[RC_v16i8] = VectorRegisters; | 587 (*TypeToRegisterSet)[RC_v16i8] = VectorRegisters; |
570 (*TypeToRegisterSet)[RC_v8i16] = VectorRegisters; | 588 (*TypeToRegisterSet)[RC_v8i16] = VectorRegisters; |
571 (*TypeToRegisterSet)[RC_v4i32] = VectorRegisters; | 589 (*TypeToRegisterSet)[RC_v4i32] = VectorRegisters; |
572 (*TypeToRegisterSet)[RC_v4f32] = VectorRegisters; | 590 (*TypeToRegisterSet)[RC_v4f32] = VectorRegisters; |
573 (*TypeToRegisterSet)[RCX86_Is64To8] = Trunc64To8Registers; | 591 (*TypeToRegisterSet)[RCX86_Is64To8] = Trunc64To8Registers; |
574 (*TypeToRegisterSet)[RCX86_Is32To8] = Trunc32To8Registers; | 592 (*TypeToRegisterSet)[RCX86_Is32To8] = Trunc32To8Registers; |
575 (*TypeToRegisterSet)[RCX86_Is16To8] = Trunc16To8Registers; | 593 (*TypeToRegisterSet)[RCX86_Is16To8] = Trunc16To8Registers; |
576 (*TypeToRegisterSet)[RCX86_IsTrunc8Rcvr] = Trunc8RcvrRegisters; | 594 (*TypeToRegisterSet)[RCX86_IsTrunc8Rcvr] = Trunc8RcvrRegisters; |
577 (*TypeToRegisterSet)[RCX86_IsAhRcvr] = AhRcvrRegisters; | 595 (*TypeToRegisterSet)[RCX86_IsAhRcvr] = AhRcvrRegisters; |
578 } | 596 } |
579 | 597 |
580 static llvm::SmallBitVector | 598 static llvm::SmallBitVector |
581 getRegisterSet(TargetLowering::RegSetMask Include, | 599 getRegisterSet(const ::Ice::ClFlags &Flags, |
600 TargetLowering::RegSetMask Include, | |
582 TargetLowering::RegSetMask Exclude) { | 601 TargetLowering::RegSetMask Exclude) { |
583 llvm::SmallBitVector Registers(RegisterSet::Reg_NUM); | 602 llvm::SmallBitVector Registers(RegisterSet::Reg_NUM); |
584 | 603 |
604 const bool NeedSandboxing = Flags.getUseSandboxing(); | |
585 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 605 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
586 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 606 sboxres, isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, \ |
587 isTrunc8Rcvr, isAhRcvr, aliases) \ | 607 is16To8, isTrunc8Rcvr, isAhRcvr, aliases) \ |
588 if (scratch && (Include & ::Ice::TargetLowering::RegSet_CallerSave)) \ | 608 if (!NeedSandboxing || !(sboxres)) { \ |
589 Registers[RegisterSet::val] = true; \ | 609 if (scratch && (Include & ::Ice::TargetLowering::RegSet_CallerSave)) \ |
590 if (preserved && (Include & ::Ice::TargetLowering::RegSet_CalleeSave)) \ | 610 Registers[RegisterSet::val] = true; \ |
591 Registers[RegisterSet::val] = true; \ | 611 if (preserved && (Include & ::Ice::TargetLowering::RegSet_CalleeSave)) \ |
592 if (stackptr && (Include & ::Ice::TargetLowering::RegSet_StackPointer)) \ | 612 Registers[RegisterSet::val] = true; \ |
593 Registers[RegisterSet::val] = true; \ | 613 if (stackptr && (Include & ::Ice::TargetLowering::RegSet_StackPointer)) \ |
594 if (frameptr && (Include & ::Ice::TargetLowering::RegSet_FramePointer)) \ | 614 Registers[RegisterSet::val] = true; \ |
595 Registers[RegisterSet::val] = true; \ | 615 if (frameptr && (Include & ::Ice::TargetLowering::RegSet_FramePointer)) \ |
596 if (scratch && (Exclude & ::Ice::TargetLowering::RegSet_CallerSave)) \ | 616 Registers[RegisterSet::val] = true; \ |
597 Registers[RegisterSet::val] = false; \ | 617 if (scratch && (Exclude & ::Ice::TargetLowering::RegSet_CallerSave)) \ |
598 if (preserved && (Exclude & ::Ice::TargetLowering::RegSet_CalleeSave)) \ | 618 Registers[RegisterSet::val] = false; \ |
599 Registers[RegisterSet::val] = false; \ | 619 if (preserved && (Exclude & ::Ice::TargetLowering::RegSet_CalleeSave)) \ |
600 if (stackptr && (Exclude & ::Ice::TargetLowering::RegSet_StackPointer)) \ | 620 Registers[RegisterSet::val] = false; \ |
601 Registers[RegisterSet::val] = false; \ | 621 if (stackptr && (Exclude & ::Ice::TargetLowering::RegSet_StackPointer)) \ |
602 if (frameptr && (Exclude & ::Ice::TargetLowering::RegSet_FramePointer)) \ | 622 Registers[RegisterSet::val] = false; \ |
603 Registers[RegisterSet::val] = false; | 623 if (frameptr && (Exclude & ::Ice::TargetLowering::RegSet_FramePointer)) \ |
624 Registers[RegisterSet::val] = false; \ | |
625 } | |
604 | 626 |
605 REGX8664_TABLE | 627 REGX8664_TABLE |
606 | 628 |
607 #undef X | 629 #undef X |
608 | 630 |
609 return Registers; | 631 return Registers; |
610 } | 632 } |
611 | 633 |
612 static void | 634 static void |
613 makeRandomRegisterPermutation(GlobalContext *Ctx, Cfg *Func, | 635 makeRandomRegisterPermutation(GlobalContext *Ctx, Cfg *Func, |
614 llvm::SmallVectorImpl<int32_t> &Permutation, | 636 llvm::SmallVectorImpl<int32_t> &Permutation, |
615 const llvm::SmallBitVector &ExcludeRegisters, | 637 const llvm::SmallBitVector &ExcludeRegisters, |
616 uint64_t Salt) { | 638 uint64_t Salt) { |
617 // TODO(stichnot): Declaring Permutation this way loses type/size | 639 // TODO(stichnot): Declaring Permutation this way loses type/size |
618 // information. Fix this in conjunction with the caller-side TODO. | 640 // information. Fix this in conjunction with the caller-side TODO. |
619 assert(Permutation.size() >= RegisterSet::Reg_NUM); | 641 assert(Permutation.size() >= RegisterSet::Reg_NUM); |
620 // Expected upper bound on the number of registers in a single equivalence | 642 // Expected upper bound on the number of registers in a single equivalence |
621 // class. For x86-64, this would comprise the 16 XMM registers. This is | 643 // class. For x86-64, this would comprise the 16 XMM registers. This is |
622 // for performance, not correctness. | 644 // for performance, not correctness. |
623 static const unsigned MaxEquivalenceClassSize = 8; | 645 static const unsigned MaxEquivalenceClassSize = 8; |
624 using RegisterList = llvm::SmallVector<int32_t, MaxEquivalenceClassSize>; | 646 using RegisterList = llvm::SmallVector<int32_t, MaxEquivalenceClassSize>; |
625 using EquivalenceClassMap = std::map<uint32_t, RegisterList>; | 647 using EquivalenceClassMap = std::map<uint32_t, RegisterList>; |
626 EquivalenceClassMap EquivalenceClasses; | 648 EquivalenceClassMap EquivalenceClasses; |
627 SizeT NumShuffled = 0, NumPreserved = 0; | 649 SizeT NumShuffled = 0, NumPreserved = 0; |
628 | 650 |
629 // Build up the equivalence classes of registers by looking at the register | 651 // Build up the equivalence classes of registers by looking at the register |
630 // properties as well as whether the registers should be explicitly excluded | 652 // properties as well as whether the registers should be explicitly excluded |
631 // from shuffling. | 653 // from shuffling. |
632 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 654 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
633 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 655 sboxres, isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, \ |
634 isTrunc8Rcvr, isAhRcvr, aliases) \ | 656 is16To8, isTrunc8Rcvr, isAhRcvr, aliases) \ |
635 if (ExcludeRegisters[RegisterSet::val]) { \ | 657 if (ExcludeRegisters[RegisterSet::val]) { \ |
636 /* val stays the same in the resulting permutation. */ \ | 658 /* val stays the same in the resulting permutation. */ \ |
637 Permutation[RegisterSet::val] = RegisterSet::val; \ | 659 Permutation[RegisterSet::val] = RegisterSet::val; \ |
638 ++NumPreserved; \ | 660 ++NumPreserved; \ |
639 } else { \ | 661 } else { \ |
640 uint32_t AttrKey = 0; \ | 662 uint32_t AttrKey = 0; \ |
641 uint32_t Index = 0; \ | 663 uint32_t Index = 0; \ |
642 /* Combine relevant attributes into an equivalence class key. */ \ | 664 /* Combine relevant attributes into an equivalence class key. */ \ |
643 Index |= (scratch << (AttrKey++)); \ | 665 Index |= (scratch << (AttrKey++)); \ |
644 Index |= (preserved << (AttrKey++)); \ | 666 Index |= (preserved << (AttrKey++)); \ |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
838 X86OperandMem() = delete; | 860 X86OperandMem() = delete; |
839 X86OperandMem(const X86OperandMem &) = delete; | 861 X86OperandMem(const X86OperandMem &) = delete; |
840 X86OperandMem &operator=(const X86OperandMem &) = delete; | 862 X86OperandMem &operator=(const X86OperandMem &) = delete; |
841 | 863 |
842 public: | 864 public: |
843 enum SegmentRegisters { DefaultSegment = -1, SegReg_NUM }; | 865 enum SegmentRegisters { DefaultSegment = -1, SegReg_NUM }; |
844 static X86OperandMem * | 866 static X86OperandMem * |
845 create(Cfg *Func, Type Ty, Variable *Base, Constant *Offset, | 867 create(Cfg *Func, Type Ty, Variable *Base, Constant *Offset, |
846 Variable *Index = nullptr, uint16_t Shift = 0, | 868 Variable *Index = nullptr, uint16_t Shift = 0, |
847 SegmentRegisters SegmentRegister = DefaultSegment, | 869 SegmentRegisters SegmentRegister = DefaultSegment, |
848 bool IsPIC = false) { | 870 bool IsRebased = false) { |
849 assert(SegmentRegister == DefaultSegment); | 871 assert(SegmentRegister == DefaultSegment); |
850 (void)SegmentRegister; | 872 (void)SegmentRegister; |
851 return new (Func->allocate<X86OperandMem>()) | 873 return new (Func->allocate<X86OperandMem>()) |
852 X86OperandMem(Func, Ty, Base, Offset, Index, Shift, IsPIC); | 874 X86OperandMem(Func, Ty, Base, Offset, Index, Shift, IsRebased); |
875 } | |
876 static X86OperandMem *create(Cfg *Func, Type Ty, Variable *Base, | |
877 Constant *Offset, bool IsRebased) { | |
878 constexpr Variable *NoIndex = nullptr; | |
879 constexpr uint16_t NoShift = 0; | |
880 return new (Func->allocate<X86OperandMem>()) | |
881 X86OperandMem(Func, Ty, Base, Offset, NoIndex, NoShift, IsRebased); | |
853 } | 882 } |
854 Variable *getBase() const { return Base; } | 883 Variable *getBase() const { return Base; } |
855 Constant *getOffset() const { return Offset; } | 884 Constant *getOffset() const { return Offset; } |
856 Variable *getIndex() const { return Index; } | 885 Variable *getIndex() const { return Index; } |
857 uint16_t getShift() const { return Shift; } | 886 uint16_t getShift() const { return Shift; } |
858 SegmentRegisters getSegmentRegister() const { return DefaultSegment; } | 887 SegmentRegisters getSegmentRegister() const { return DefaultSegment; } |
859 void emitSegmentOverride(Assembler *) const {} | 888 void emitSegmentOverride(Assembler *) const {} |
860 void setIsPIC() { IsPIC = true; } | 889 bool getIsRebased() const { return IsRebased; } |
861 bool getIsPIC() const { return IsPIC; } | 890 Address toAsmAddress(Assembler *Asm, const Ice::TargetLowering *Target, |
862 Address toAsmAddress(Assembler *Asm, | 891 bool IsLeaAddr = false) const; |
863 const Ice::TargetLowering *Target) const; | |
864 | 892 |
865 void emit(const Cfg *Func) const override; | 893 void emit(const Cfg *Func) const override; |
866 using X86Operand::dump; | 894 using X86Operand::dump; |
867 void dump(const Cfg *Func, Ostream &Str) const override; | 895 void dump(const Cfg *Func, Ostream &Str) const override; |
868 | 896 |
869 static bool classof(const Operand *Operand) { | 897 static bool classof(const Operand *Operand) { |
870 return Operand->getKind() == static_cast<OperandKind>(kMem); | 898 return Operand->getKind() == static_cast<OperandKind>(kMem); |
871 } | 899 } |
872 | 900 |
873 void setRandomized(bool R) { Randomized = R; } | 901 void setRandomized(bool R) { Randomized = R; } |
874 | 902 |
875 bool getRandomized() const { return Randomized; } | 903 bool getRandomized() const { return Randomized; } |
876 | 904 |
877 private: | 905 private: |
878 X86OperandMem(Cfg *Func, Type Ty, Variable *Base, Constant *Offset, | 906 X86OperandMem(Cfg *Func, Type Ty, Variable *Base, Constant *Offset, |
879 Variable *Index, uint16_t Shift, bool IsPIC); | 907 Variable *Index, uint16_t Shift, bool IsRebased); |
880 | 908 |
881 Variable *Base; | 909 Variable *const Base; |
882 Constant *Offset; | 910 Constant *const Offset; |
883 Variable *Index; | 911 Variable *const Index; |
884 uint16_t Shift; | 912 const uint16_t Shift; |
885 bool IsPIC; | 913 const bool IsRebased; |
886 /// A flag to show if this memory operand is a randomized one. Randomized | 914 /// A flag to show if this memory operand is a randomized one. Randomized |
887 /// memory operands are generated in | 915 /// memory operands are generated in |
888 /// TargetX86Base::randomizeOrPoolImmediate() | 916 /// TargetX86Base::randomizeOrPoolImmediate() |
889 bool Randomized = false; | 917 bool Randomized = false; |
890 }; | 918 }; |
891 | 919 |
892 /// VariableSplit is a way to treat an f64 memory location as a pair of i32 | 920 /// VariableSplit is a way to treat an f64 memory location as a pair of i32 |
893 /// locations (Low and High). This is needed for some cases of the Bitcast | 921 /// locations (Low and High). This is needed for some cases of the Bitcast |
894 /// instruction. Since it's not possible for integer registers to access the | 922 /// instruction. Since it's not possible for integer registers to access the |
895 /// XMM registers and vice versa, the lowering forces the f64 to be spilled to | 923 /// XMM registers and vice versa, the lowering forces the f64 to be spilled to |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
982 const char *FldString; // s, l, or <blank> | 1010 const char *FldString; // s, l, or <blank> |
983 } TypeAttributes[]; | 1011 } TypeAttributes[]; |
984 }; | 1012 }; |
985 | 1013 |
986 using Traits = ::Ice::X8664::TargetX8664Traits; | 1014 using Traits = ::Ice::X8664::TargetX8664Traits; |
987 } // end of namespace X8664 | 1015 } // end of namespace X8664 |
988 | 1016 |
989 } // end of namespace Ice | 1017 } // end of namespace Ice |
990 | 1018 |
991 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8664TRAITS_H | 1019 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8664TRAITS_H |
OLD | NEW |