OLD | NEW |
1 //===-- X86FrameLowering.cpp - X86 Frame Information ----------------------===// | 1 //===-- X86FrameLowering.cpp - X86 Frame Information ----------------------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
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 // This file contains the X86 implementation of TargetFrameLowering class. | 10 // This file contains the X86 implementation of TargetFrameLowering class. |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
365 | 365 |
366 MachineLocation CSDst(MachineLocation::VirtualFP, Offset); | 366 MachineLocation CSDst(MachineLocation::VirtualFP, Offset); |
367 MachineLocation CSSrc(Reg); | 367 MachineLocation CSSrc(Reg); |
368 Moves.push_back(MachineMove(Label, CSDst, CSSrc)); | 368 Moves.push_back(MachineMove(Label, CSDst, CSSrc)); |
369 } | 369 } |
370 } | 370 } |
371 | 371 |
372 /// getCompactUnwindRegNum - Get the compact unwind number for a given | 372 /// getCompactUnwindRegNum - Get the compact unwind number for a given |
373 /// register. The number corresponds to the enum lists in | 373 /// register. The number corresponds to the enum lists in |
374 /// compact_unwind_encoding.h. | 374 /// compact_unwind_encoding.h. |
375 static int getCompactUnwindRegNum(unsigned Reg, bool is64Bit) { | 375 static int getCompactUnwindRegNum(const uint16_t *CURegs, unsigned Reg) { |
376 static const uint16_t CU32BitRegs[] = { | |
377 X86::EBX, X86::ECX, X86::EDX, X86::EDI, X86::ESI, X86::EBP, 0 | |
378 }; | |
379 static const uint16_t CU64BitRegs[] = { | |
380 X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0 | |
381 }; | |
382 const uint16_t *CURegs = is64Bit ? CU64BitRegs : CU32BitRegs; | |
383 for (int Idx = 1; *CURegs; ++CURegs, ++Idx) | 376 for (int Idx = 1; *CURegs; ++CURegs, ++Idx) |
384 if (*CURegs == Reg) | 377 if (*CURegs == Reg) |
385 return Idx; | 378 return Idx; |
386 | 379 |
387 return -1; | 380 return -1; |
388 } | 381 } |
389 | 382 |
390 // Number of registers that can be saved in a compact unwind encoding. | 383 // Number of registers that can be saved in a compact unwind encoding. |
391 #define CU_NUM_SAVED_REGS 6 | 384 #define CU_NUM_SAVED_REGS 6 |
392 | 385 |
393 /// encodeCompactUnwindRegistersWithoutFrame - Create the permutation encoding | 386 /// encodeCompactUnwindRegistersWithoutFrame - Create the permutation encoding |
394 /// used with frameless stacks. It is passed the number of registers to be saved | 387 /// used with frameless stacks. It is passed the number of registers to be saved |
395 /// and an array of the registers saved. | 388 /// and an array of the registers saved. |
396 static uint32_t | 389 static uint32_t |
397 encodeCompactUnwindRegistersWithoutFrame(unsigned SavedRegs[CU_NUM_SAVED_REGS], | 390 encodeCompactUnwindRegistersWithoutFrame(unsigned SavedRegs[CU_NUM_SAVED_REGS], |
398 unsigned RegCount, bool Is64Bit) { | 391 unsigned RegCount, bool Is64Bit) { |
399 // The saved registers are numbered from 1 to 6. In order to encode the order | 392 // The saved registers are numbered from 1 to 6. In order to encode the order |
400 // in which they were saved, we re-number them according to their place in the | 393 // in which they were saved, we re-number them according to their place in the |
401 // register order. The re-numbering is relative to the last re-numbered | 394 // register order. The re-numbering is relative to the last re-numbered |
402 // register. E.g., if we have registers {6, 2, 4, 5} saved in that order: | 395 // register. E.g., if we have registers {6, 2, 4, 5} saved in that order: |
403 // | 396 // |
404 // Orig Re-Num | 397 // Orig Re-Num |
405 // ---- ------ | 398 // ---- ------ |
406 // 6 6 | 399 // 6 6 |
407 // 2 2 | 400 // 2 2 |
408 // 4 3 | 401 // 4 3 |
409 // 5 3 | 402 // 5 3 |
410 // | 403 // |
| 404 static const uint16_t CU32BitRegs[] = { |
| 405 X86::EBX, X86::ECX, X86::EDX, X86::EDI, X86::ESI, X86::EBP, 0 |
| 406 }; |
| 407 static const uint16_t CU64BitRegs[] = { |
| 408 X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0 |
| 409 }; |
| 410 const uint16_t *CURegs = (Is64Bit ? CU64BitRegs : CU32BitRegs); |
| 411 |
411 for (unsigned i = 0; i != CU_NUM_SAVED_REGS; ++i) { | 412 for (unsigned i = 0; i != CU_NUM_SAVED_REGS; ++i) { |
412 int CUReg = getCompactUnwindRegNum(SavedRegs[i], Is64Bit); | 413 int CUReg = getCompactUnwindRegNum(CURegs, SavedRegs[i]); |
413 if (CUReg == -1) return ~0U; | 414 if (CUReg == -1) return ~0U; |
414 SavedRegs[i] = CUReg; | 415 SavedRegs[i] = CUReg; |
415 } | 416 } |
416 | 417 |
417 // Reverse the list. | 418 // Reverse the list. |
418 std::swap(SavedRegs[0], SavedRegs[5]); | 419 std::swap(SavedRegs[0], SavedRegs[5]); |
419 std::swap(SavedRegs[1], SavedRegs[4]); | 420 std::swap(SavedRegs[1], SavedRegs[4]); |
420 std::swap(SavedRegs[2], SavedRegs[3]); | 421 std::swap(SavedRegs[2], SavedRegs[3]); |
421 | 422 |
422 uint32_t RenumRegs[CU_NUM_SAVED_REGS]; | 423 uint32_t RenumRegs[CU_NUM_SAVED_REGS]; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 assert((permutationEncoding & 0x3FF) == permutationEncoding && | 462 assert((permutationEncoding & 0x3FF) == permutationEncoding && |
462 "Invalid compact register encoding!"); | 463 "Invalid compact register encoding!"); |
463 return permutationEncoding; | 464 return permutationEncoding; |
464 } | 465 } |
465 | 466 |
466 /// encodeCompactUnwindRegistersWithFrame - Return the registers encoded for a | 467 /// encodeCompactUnwindRegistersWithFrame - Return the registers encoded for a |
467 /// compact encoding with a frame pointer. | 468 /// compact encoding with a frame pointer. |
468 static uint32_t | 469 static uint32_t |
469 encodeCompactUnwindRegistersWithFrame(unsigned SavedRegs[CU_NUM_SAVED_REGS], | 470 encodeCompactUnwindRegistersWithFrame(unsigned SavedRegs[CU_NUM_SAVED_REGS], |
470 bool Is64Bit) { | 471 bool Is64Bit) { |
| 472 static const uint16_t CU32BitRegs[] = { |
| 473 X86::EBX, X86::ECX, X86::EDX, X86::EDI, X86::ESI, X86::EBP, 0 |
| 474 }; |
| 475 static const uint16_t CU64BitRegs[] = { |
| 476 X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0 |
| 477 }; |
| 478 const uint16_t *CURegs = (Is64Bit ? CU64BitRegs : CU32BitRegs); |
| 479 |
471 // Encode the registers in the order they were saved, 3-bits per register. The | 480 // Encode the registers in the order they were saved, 3-bits per register. The |
472 // registers are numbered from 1 to CU_NUM_SAVED_REGS. | 481 // registers are numbered from 1 to CU_NUM_SAVED_REGS. |
473 uint32_t RegEnc = 0; | 482 uint32_t RegEnc = 0; |
474 for (int I = CU_NUM_SAVED_REGS - 1, Idx = 0; I != -1; --I) { | 483 for (int I = CU_NUM_SAVED_REGS - 1, Idx = 0; I != -1; --I) { |
475 unsigned Reg = SavedRegs[I]; | 484 unsigned Reg = SavedRegs[I]; |
476 if (Reg == 0) continue; | 485 if (Reg == 0) continue; |
477 | 486 |
478 int CURegNum = getCompactUnwindRegNum(Reg, Is64Bit); | 487 int CURegNum = getCompactUnwindRegNum(CURegs, Reg); |
479 if (CURegNum == -1) return ~0U; | 488 if (CURegNum == -1) return ~0U; |
480 | 489 |
481 // Encode the 3-bit register number in order, skipping over 3-bits for each | 490 // Encode the 3-bit register number in order, skipping over 3-bits for each |
482 // register. | 491 // register. |
483 RegEnc |= (CURegNum & 0x7) << (Idx++ * 3); | 492 RegEnc |= (CURegNum & 0x7) << (Idx++ * 3); |
484 } | 493 } |
485 | 494 |
486 assert((RegEnc & 0x3FFFF) == RegEnc && "Invalid compact register encoding!"); | 495 assert((RegEnc & 0x3FFFF) == RegEnc && "Invalid compact register encoding!"); |
487 return RegEnc; | 496 return RegEnc; |
488 } | 497 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
521 if (Opc == X86::PROLOG_LABEL) continue; | 530 if (Opc == X86::PROLOG_LABEL) continue; |
522 if (!MI.getFlag(MachineInstr::FrameSetup)) break; | 531 if (!MI.getFlag(MachineInstr::FrameSetup)) break; |
523 | 532 |
524 // We don't exect any more prolog instructions. | 533 // We don't exect any more prolog instructions. |
525 if (ExpectEnd) return CU::UNWIND_MODE_DWARF; | 534 if (ExpectEnd) return CU::UNWIND_MODE_DWARF; |
526 | 535 |
527 if (Opc == PushInstr) { | 536 if (Opc == PushInstr) { |
528 // If there are too many saved registers, we cannot use compact encoding. | 537 // If there are too many saved registers, we cannot use compact encoding. |
529 if (SavedRegIdx >= CU_NUM_SAVED_REGS) return CU::UNWIND_MODE_DWARF; | 538 if (SavedRegIdx >= CU_NUM_SAVED_REGS) return CU::UNWIND_MODE_DWARF; |
530 | 539 |
531 unsigned Reg = MI.getOperand(0).getReg(); | |
532 if (Reg == (Is64Bit ? X86::RAX : X86::EAX)) { | |
533 ExpectEnd = true; | |
534 continue; | |
535 } | |
536 | |
537 SavedRegs[SavedRegIdx++] = MI.getOperand(0).getReg(); | 540 SavedRegs[SavedRegIdx++] = MI.getOperand(0).getReg(); |
538 StackAdjust += OffsetSize; | 541 StackAdjust += OffsetSize; |
539 InstrOffset += PushInstrSize; | 542 InstrOffset += PushInstrSize; |
540 } else if (Opc == MoveInstr) { | 543 } else if (Opc == MoveInstr) { |
541 unsigned SrcReg = MI.getOperand(1).getReg(); | 544 unsigned SrcReg = MI.getOperand(1).getReg(); |
542 unsigned DstReg = MI.getOperand(0).getReg(); | 545 unsigned DstReg = MI.getOperand(0).getReg(); |
543 | 546 |
544 if (DstReg != FramePtr || SrcReg != StackPtr) | 547 if (DstReg != FramePtr || SrcReg != StackPtr) |
545 return CU::UNWIND_MODE_DWARF; | 548 return CU::UNWIND_MODE_DWARF; |
546 | 549 |
(...skipping 1347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1894 // We are not tracking the stack pointer adjustment by the callee, so make | 1897 // We are not tracking the stack pointer adjustment by the callee, so make |
1895 // sure we restore the stack pointer immediately after the call, there may | 1898 // sure we restore the stack pointer immediately after the call, there may |
1896 // be spill code inserted between the CALL and ADJCALLSTACKUP instructions. | 1899 // be spill code inserted between the CALL and ADJCALLSTACKUP instructions. |
1897 MachineBasicBlock::iterator B = MBB.begin(); | 1900 MachineBasicBlock::iterator B = MBB.begin(); |
1898 while (I != B && !llvm::prior(I)->isCall()) | 1901 while (I != B && !llvm::prior(I)->isCall()) |
1899 --I; | 1902 --I; |
1900 MBB.insert(I, New); | 1903 MBB.insert(I, New); |
1901 } | 1904 } |
1902 } | 1905 } |
1903 | 1906 |
OLD | NEW |