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

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: Fixes filetype=asm; addresses 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
« no previous file with comments | « src/IceTargetLoweringX8664.cpp ('k') | src/IceTargetLoweringX86Base.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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 alias table still needs to be defined.
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
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
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
OLDNEW
« no previous file with comments | « src/IceTargetLoweringX8664.cpp ('k') | src/IceTargetLoweringX86Base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698