Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(717)

Side by Side Diff: src/IceTargetLoweringX8664Traits.h

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

Powered by Google App Engine
This is Rietveld 408576698