llvm.org GIT mirror llvm / c3cee57
Generate compact unwind encoding from CFI directives. We used to generate the compact unwind encoding from the machine instructions. However, this had the problem that if the user used `-save-temps' or compiled their hand-written `.s' file (with CFI directives), we wouldn't generate the compact unwind encoding. Move the algorithm that generates the compact unwind encoding into the MCAsmBackend. This way we can generate the encoding whether the code is from a `.ll' or `.s' file. <rdar://problem/13623355> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190290 91177308-0d34-0410-b5e6-96231b3b80d8 Bill Wendling 6 years ago
25 changed file(s) with 454 addition(s) and 363 deletion(s). Raw diff Collapse all Expand all
99 #ifndef LLVM_MC_MCASMBACKEND_H
1010 #define LLVM_MC_MCASMBACKEND_H
1111
12 #include "llvm/ADT/ArrayRef.h"
1213 #include "llvm/MC/MCDirectives.h"
14 #include "llvm/MC/MCDwarf.h"
1315 #include "llvm/MC/MCFixup.h"
1416 #include "llvm/Support/DataTypes.h"
1517 #include "llvm/Support/ErrorHandling.h"
157159 /// handleAssemblerFlag - Handle any target-specific assembler flags.
158160 /// By default, do nothing.
159161 virtual void handleAssemblerFlag(MCAssemblerFlag Flag) {}
162
163 /// \brief Generate the compact unwind encoding for the CFI instructions.
164 virtual unsigned
165 generateCompactUnwindEncoding(ArrayRef) const {
166 return 0;
167 }
160168 };
161169
162170 } // End llvm namespace
132132 MCWin64EHUnwindInfo &getW64UnwindInfo(unsigned i) {
133133 return *W64UnwindInfos[i];
134134 }
135
136 void generateCompactUnwindEncodings(MCAsmBackend &MAB);
135137
136138 /// @name Assembly File Formatting.
137139 /// @{
103103 typedef AsmPrinter *(*AsmPrinterCtorTy)(TargetMachine &TM,
104104 MCStreamer &Streamer);
105105 typedef MCAsmBackend *(*MCAsmBackendCtorTy)(const Target &T,
106 const MCRegisterInfo &MRI,
106107 StringRef TT,
107108 StringRef CPU);
108109 typedef MCTargetAsmParser *(*MCAsmParserCtorTy)(MCSubtargetInfo &STI,
372373 /// createMCAsmBackend - Create a target specific assembly parser.
373374 ///
374375 /// \param Triple The target triple string.
375 MCAsmBackend *createMCAsmBackend(StringRef Triple, StringRef CPU) const {
376 MCAsmBackend *createMCAsmBackend(const MCRegisterInfo &MRI,
377 StringRef Triple, StringRef CPU) const {
376378 if (!MCAsmBackendCtorFn)
377379 return 0;
378 return MCAsmBackendCtorFn(*this, Triple, CPU);
380 return MCAsmBackendCtorFn(*this, MRI, Triple, CPU);
379381 }
380382
381383 /// createMCAsmParser - Create a target specific assembly parser.
11171119 }
11181120
11191121 private:
1120 static MCAsmBackend *Allocator(const Target &T, StringRef Triple,
1121 StringRef CPU) {
1122 return new MCAsmBackendImpl(T, Triple, CPU);
1122 static MCAsmBackend *Allocator(const Target &T,
1123 const MCRegisterInfo &MRI,
1124 StringRef Triple, StringRef CPU) {
1125 return new MCAsmBackendImpl(T, MRI, Triple, CPU);
11231126 }
11241127 };
11251128
177177 MCAsmBackend *MAB = 0;
178178 if (ShowMCEncoding) {
179179 MCE = getTarget().createMCCodeEmitter(MII, MRI, STI, *Context);
180 MAB = getTarget().createMCAsmBackend(getTargetTriple(), TargetCPU);
180 MAB = getTarget().createMCAsmBackend(MRI, getTargetTriple(), TargetCPU);
181181 }
182182
183183 MCStreamer *S = getTarget().createAsmStreamer(*Context, Out,
196196 // emission fails.
197197 MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, MRI, STI,
198198 *Context);
199 MCAsmBackend *MAB = getTarget().createMCAsmBackend(getTargetTriple(),
199 MCAsmBackend *MAB = getTarget().createMCAsmBackend(MRI, getTargetTriple(),
200200 TargetCPU);
201201 if (MCE == 0 || MAB == 0)
202202 return true;
270270 const MCSubtargetInfo &STI = getSubtarget();
271271 MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(*getInstrInfo(), MRI,
272272 STI, *Ctx);
273 MCAsmBackend *MAB = getTarget().createMCAsmBackend(getTargetTriple(), TargetCPU);
273 MCAsmBackend *MAB = getTarget().createMCAsmBackend(MRI, getTargetTriple(),
274 TargetCPU);
274275 if (MCE == 0 || MAB == 0)
275276 return true;
276277
395395 }
396396
397397 void MCMachOStreamer::FinishImpl() {
398 generateCompactUnwindEncodings(getAssembler().getBackend());
398399 EmitFrames(true);
399400
400401 // We have to set the fragment atom associations so we can relax properly for
99 #include "llvm/MC/MCStreamer.h"
1010 #include "llvm/ADT/SmallString.h"
1111 #include "llvm/ADT/Twine.h"
12 #include "llvm/MC/MCAsmBackend.h"
1213 #include "llvm/MC/MCAsmInfo.h"
1314 #include "llvm/MC/MCContext.h"
1415 #include "llvm/MC/MCExpr.h"
6970 raw_ostream &MCStreamer::GetCommentOS() {
7071 // By default, discard comments.
7172 return nulls();
73 }
74
75 void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend &MAB) {
76 for (std::vector::iterator I = FrameInfos.begin(),
77 E = FrameInfos.end(); I != E; ++I)
78 if (!I->CompactUnwindEncoding)
79 I->CompactUnwindEncoding =
80 MAB.generateCompactUnwindEncoding(I->Instructions);
7281 }
7382
7483 void MCStreamer::EmitDwarfSetLineAddr(int64_t LineDelta,
577577 }
578578
579579 MCAsmBackend *
580 llvm::createAArch64AsmBackend(const Target &T, StringRef TT, StringRef CPU) {
580 llvm::createAArch64AsmBackend(const Target &T, const MCRegisterInfo &MRI,
581 StringRef TT, StringRef CPU) {
581582 Triple TheTriple(TT);
582
583583 return new ELFAArch64AsmBackend(T, TT, TheTriple.getOS());
584584 }
4242 MCObjectWriter *createAArch64ELFObjectWriter(raw_ostream &OS,
4343 uint8_t OSABI);
4444
45 MCAsmBackend *createAArch64AsmBackend(const Target &T, StringRef TT,
46 StringRef CPU);
45 MCAsmBackend *createAArch64AsmBackend(const Target &T,
46 const MCRegisterInfo &MRI,
47 StringRef TT, StringRef CPU);
4748
4849 } // End llvm namespace
4950
659659
660660 } // end anonymous namespace
661661
662 MCAsmBackend *llvm::createARMAsmBackend(const Target &T, StringRef TT, StringRef CPU) {
662 MCAsmBackend *llvm::createARMAsmBackend(const Target &T,
663 const MCRegisterInfo &MRI,
664 StringRef TT, StringRef CPU) {
663665 Triple TheTriple(TT);
664666
665667 if (TheTriple.isOSDarwin()) {
4646 const MCSubtargetInfo &STI,
4747 MCContext &Ctx);
4848
49 MCAsmBackend *createARMAsmBackend(const Target &T, StringRef TT, StringRef CPU);
49 MCAsmBackend *createARMAsmBackend(const Target &T, const MCRegisterInfo &MRI,
50 StringRef TT, StringRef CPU);
5051
5152 /// createARMELFObjectWriter - Construct an ELF Mach-O object writer.
5253 MCObjectWriter *createARMELFObjectWriter(raw_ostream &OS,
252252 } // namespace
253253
254254 // MCAsmBackend
255 MCAsmBackend *llvm::createMipsAsmBackendEL32(const Target &T, StringRef TT,
255 MCAsmBackend *llvm::createMipsAsmBackendEL32(const Target &T,
256 const MCRegisterInfo &MRI,
257 StringRef TT,
256258 StringRef CPU) {
257259 return new MipsAsmBackend(T, Triple(TT).getOS(),
258260 /*IsLittle*/true, /*Is64Bit*/false);
259261 }
260262
261 MCAsmBackend *llvm::createMipsAsmBackendEB32(const Target &T, StringRef TT,
263 MCAsmBackend *llvm::createMipsAsmBackendEB32(const Target &T,
264 const MCRegisterInfo &MRI,
265 StringRef TT,
262266 StringRef CPU) {
263267 return new MipsAsmBackend(T, Triple(TT).getOS(),
264268 /*IsLittle*/false, /*Is64Bit*/false);
265269 }
266270
267 MCAsmBackend *llvm::createMipsAsmBackendEL64(const Target &T, StringRef TT,
271 MCAsmBackend *llvm::createMipsAsmBackendEL64(const Target &T,
272 const MCRegisterInfo &MRI,
273 StringRef TT,
268274 StringRef CPU) {
269275 return new MipsAsmBackend(T, Triple(TT).getOS(),
270276 /*IsLittle*/true, /*Is64Bit*/true);
271277 }
272278
273 MCAsmBackend *llvm::createMipsAsmBackendEB64(const Target &T, StringRef TT,
279 MCAsmBackend *llvm::createMipsAsmBackendEB64(const Target &T,
280 const MCRegisterInfo &MRI,
281 StringRef TT,
274282 StringRef CPU) {
275283 return new MipsAsmBackend(T, Triple(TT).getOS(),
276284 /*IsLittle*/false, /*Is64Bit*/true);
4141 const MCSubtargetInfo &STI,
4242 MCContext &Ctx);
4343
44 MCAsmBackend *createMipsAsmBackendEB32(const Target &T, StringRef TT,
45 StringRef CPU);
46 MCAsmBackend *createMipsAsmBackendEL32(const Target &T, StringRef TT,
47 StringRef CPU);
48 MCAsmBackend *createMipsAsmBackendEB64(const Target &T, StringRef TT,
49 StringRef CPU);
50 MCAsmBackend *createMipsAsmBackendEL64(const Target &T, StringRef TT,
51 StringRef CPU);
44 MCAsmBackend *createMipsAsmBackendEB32(const Target &T, const MCRegisterInfo &MRI,
45 StringRef TT, StringRef CPU);
46 MCAsmBackend *createMipsAsmBackendEL32(const Target &T, const MCRegisterInfo &MRI,
47 StringRef TT, StringRef CPU);
48 MCAsmBackend *createMipsAsmBackendEB64(const Target &T, const MCRegisterInfo &MRI,
49 StringRef TT, StringRef CPU);
50 MCAsmBackend *createMipsAsmBackendEL64(const Target &T, const MCRegisterInfo &MRI,
51 StringRef TT, StringRef CPU);
5252
5353 MCObjectWriter *createMipsELFObjectWriter(raw_ostream &OS,
5454 uint8_t OSABI,
191191
192192 } // end anonymous namespace
193193
194
195
196
197 MCAsmBackend *llvm::createPPCAsmBackend(const Target &T, StringRef TT, StringRef CPU) {
194 MCAsmBackend *llvm::createPPCAsmBackend(const Target &T,
195 const MCRegisterInfo &MRI,
196 StringRef TT, StringRef CPU) {
198197 if (Triple(TT).isOSDarwin())
199198 return new DarwinPPCAsmBackend(T);
200199
3939 const MCSubtargetInfo &STI,
4040 MCContext &Ctx);
4141
42 MCAsmBackend *createPPCAsmBackend(const Target &T, StringRef TT, StringRef CPU);
42 MCAsmBackend *createPPCAsmBackend(const Target &T, const MCRegisterInfo &MRI,
43 StringRef TT, StringRef CPU);
4344
4445 /// createPPCELFObjectWriter - Construct an PPC ELF object writer.
4546 MCObjectWriter *createPPCELFObjectWriter(raw_ostream &OS,
9494
9595 } // end anonymous namespace
9696
97 MCAsmBackend *llvm::createAMDGPUAsmBackend(const Target &T, StringRef TT,
97 MCAsmBackend *llvm::createAMDGPUAsmBackend(const Target &T,
98 const MCRegisterInfo &MRI,
99 StringRef TT,
98100 StringRef CPU) {
99101 return new ELFAMDGPUAsmBackend(T);
100102 }
3939 const MCSubtargetInfo &STI,
4040 MCContext &Ctx);
4141
42 MCAsmBackend *createAMDGPUAsmBackend(const Target &T, StringRef TT,
43 StringRef CPU);
42 MCAsmBackend *createAMDGPUAsmBackend(const Target &T, const MCRegisterInfo &MRI,
43 StringRef TT, StringRef CPU);
4444
4545 MCObjectWriter *createAMDGPUELFObjectWriter(raw_ostream &OS);
4646 } // End llvm namespace
142142 return true;
143143 }
144144
145 MCAsmBackend *llvm::createSystemZMCAsmBackend(const Target &T, StringRef TT,
146 StringRef CPU) {
145 MCAsmBackend *llvm::createSystemZMCAsmBackend(const Target &T,
146 const MCRegisterInfo &MRI,
147 StringRef TT, StringRef CPU) {
147148 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(Triple(TT).getOS());
148149 return new SystemZMCAsmBackend(OSABI);
149150 }
5353 const MCSubtargetInfo &STI,
5454 MCContext &Ctx);
5555
56 MCAsmBackend *createSystemZMCAsmBackend(const Target &T, StringRef TT,
57 StringRef CPU);
56 MCAsmBackend *createSystemZMCAsmBackend(const Target &T,
57 const MCRegisterInfo &MRI,
58 StringRef TT, StringRef CPU);
5859
5960 MCObjectWriter *createSystemZObjectWriter(raw_ostream &OS, uint8_t OSABI);
6061 } // end namespace llvm
2525 #include "llvm/Support/TargetRegistry.h"
2626 #include "llvm/Support/raw_ostream.h"
2727 using namespace llvm;
28
29 namespace CU {
30
31 /// Compact unwind encoding values.
32 enum CompactUnwindEncodings {
33 /// [RE]BP based frame where [RE]BP is pused on the stack immediately after
34 /// the return address, then [RE]SP is moved to [RE]BP.
35 UNWIND_MODE_BP_FRAME = 0x01000000,
36
37 /// A frameless function with a small constant stack size.
38 UNWIND_MODE_STACK_IMMD = 0x02000000,
39
40 /// A frameless function with a large constant stack size.
41 UNWIND_MODE_STACK_IND = 0x03000000,
42
43 /// No compact unwind encoding is available.
44 UNWIND_MODE_DWARF = 0x04000000,
45
46 /// Mask for encoding the frame registers.
47 UNWIND_BP_FRAME_REGISTERS = 0x00007FFF,
48
49 /// Mask for encoding the frameless registers.
50 UNWIND_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF
51 };
52
53 } // end CU namespace
2854
2955 // Option to allow disabling arithmetic relaxation to workaround PR9807, which
3056 // is useful when running bitwise comparison experiments on Darwin. We should be
382408 };
383409
384410 class DarwinX86AsmBackend : public X86AsmBackend {
411 const MCRegisterInfo &MRI;
412
413 /// \brief Number of registers that can be saved in a compact unwind encoding.
414 enum { CU_NUM_SAVED_REGS = 6 };
415
416 mutable unsigned SavedRegs[CU_NUM_SAVED_REGS];
417 bool Is64Bit;
418
419 unsigned OffsetSize; ///< Offset of a "push" instruction.
420 unsigned PushInstrSize; ///< Size of a "push" instruction.
421 unsigned MoveInstrSize; ///< Size of a "move" instruction.
422 unsigned StackDivide; ///< Amount to adjust stack stize by.
423 protected:
424 /// \brief Implementation of algorithm to generate the compact unwind encoding
425 /// for the CFI instructions.
426 uint32_t
427 generateCompactUnwindEncodingImpl(ArrayRef Instrs) const {
428 if (Instrs.empty()) return 0;
429
430 // Reset the saved registers.
431 unsigned SavedRegIdx = 0;
432 memset(SavedRegs, 0, sizeof(SavedRegs));
433
434 bool HasFP = false;
435
436 // Encode that we are using EBP/RBP as the frame pointer.
437 uint32_t CompactUnwindEncoding = 0;
438
439 unsigned SubtractInstrIdx = Is64Bit ? 3 : 2;
440 unsigned InstrOffset = 0;
441 unsigned StackAdjust = 0;
442 unsigned StackSize = 0;
443 unsigned PrevStackSize = 0;
444 unsigned NumDefCFAOffsets = 0;
445
446 for (unsigned i = 0, e = Instrs.size(); i != e; ++i) {
447 const MCCFIInstruction &Inst = Instrs[i];
448
449 switch (Inst.getOperation()) {
450 default:
451 llvm_unreachable("cannot handle CFI directive for compact unwind!");
452 case MCCFIInstruction::OpDefCfaRegister: {
453 // Defines a frame pointer. E.g.
454 //
455 // movq %rsp, %rbp
456 // L0:
457 // .cfi_def_cfa_register %rbp
458 //
459 HasFP = true;
460 assert(MRI.getLLVMRegNum(Inst.getRegister(), true) ==
461 (Is64Bit ? X86::RBP : X86::EBP) && "Invalid frame pointer!");
462
463 // Reset the counts.
464 memset(SavedRegs, 0, sizeof(SavedRegs));
465 StackAdjust = 0;
466 SavedRegIdx = 0;
467 InstrOffset += MoveInstrSize;
468 break;
469 }
470 case MCCFIInstruction::OpDefCfaOffset: {
471 // Defines a new offset for the CFA. E.g.
472 //
473 // With frame:
474 //
475 // pushq %rbp
476 // L0:
477 // .cfi_def_cfa_offset 16
478 //
479 // Without frame:
480 //
481 // subq $72, %rsp
482 // L0:
483 // .cfi_def_cfa_offset 80
484 //
485 PrevStackSize = StackSize;
486 StackSize = std::abs(Inst.getOffset()) / StackDivide;
487 ++NumDefCFAOffsets;
488 break;
489 }
490 case MCCFIInstruction::OpOffset: {
491 // Defines a "push" of a callee-saved register. E.g.
492 //
493 // pushq %r15
494 // pushq %r14
495 // pushq %rbx
496 // L0:
497 // subq $120, %rsp
498 // L1:
499 // .cfi_offset %rbx, -40
500 // .cfi_offset %r14, -32
501 // .cfi_offset %r15, -24
502 //
503 if (SavedRegIdx == CU_NUM_SAVED_REGS)
504 // If there are too many saved registers, we cannot use a compact
505 // unwind encoding.
506 return CU::UNWIND_MODE_DWARF;
507
508 unsigned Reg = MRI.getLLVMRegNum(Inst.getRegister(), true);
509 SavedRegs[SavedRegIdx++] = Reg;
510 StackAdjust += OffsetSize;
511 InstrOffset += PushInstrSize;
512 break;
513 }
514 }
515 }
516
517 StackAdjust /= StackDivide;
518
519 if (HasFP) {
520 if ((StackAdjust & 0xFF) != StackAdjust)
521 // Offset was too big for a compact unwind encoding.
522 return CU::UNWIND_MODE_DWARF;
523
524 // Get the encoding of the saved registers when we have a frame pointer.
525 uint32_t RegEnc = encodeCompactUnwindRegistersWithFrame();
526 if (RegEnc == ~0U) return CU::UNWIND_MODE_DWARF;
527
528 CompactUnwindEncoding |= CU::UNWIND_MODE_BP_FRAME;
529 CompactUnwindEncoding |= (StackAdjust & 0xFF) << 16;
530 CompactUnwindEncoding |= RegEnc & CU::UNWIND_BP_FRAME_REGISTERS;
531 } else {
532 // If the amount of the stack allocation is the size of a register, then
533 // we "push" the RAX/EAX register onto the stack instead of adjusting the
534 // stack pointer with a SUB instruction. We don't support the push of the
535 // RAX/EAX register with compact unwind. So we check for that situation
536 // here.
537 if ((NumDefCFAOffsets == SavedRegIdx + 1 &&
538 StackSize - PrevStackSize == 1) ||
539 (Instrs.size() == 1 && NumDefCFAOffsets == 1 && StackSize == 2))
540 return CU::UNWIND_MODE_DWARF;
541
542 SubtractInstrIdx += InstrOffset;
543 ++StackAdjust;
544
545 if ((StackSize & 0xFF) == StackSize) {
546 // Frameless stack with a small stack size.
547 CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IMMD;
548
549 // Encode the stack size.
550 CompactUnwindEncoding |= (StackSize & 0xFF) << 16;
551 } else {
552 if ((StackAdjust & 0x7) != StackAdjust)
553 // The extra stack adjustments are too big for us to handle.
554 return CU::UNWIND_MODE_DWARF;
555
556 // Frameless stack with an offset too large for us to encode compactly.
557 CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IND;
558
559 // Encode the offset to the nnnnnn value in the 'subl $nnnnnn, ESP'
560 // instruction.
561 CompactUnwindEncoding |= (SubtractInstrIdx & 0xFF) << 16;
562
563 // Encode any extra stack stack adjustments (done via push
564 // instructions).
565 CompactUnwindEncoding |= (StackAdjust & 0x7) << 13;
566 }
567
568 // Encode the number of registers saved. (Reverse the list first.)
569 std::reverse(&SavedRegs[0], &SavedRegs[SavedRegIdx]);
570 CompactUnwindEncoding |= (SavedRegIdx & 0x7) << 10;
571
572 // Get the encoding of the saved registers when we don't have a frame
573 // pointer.
574 uint32_t RegEnc = encodeCompactUnwindRegistersWithoutFrame(SavedRegIdx);
575 if (RegEnc == ~0U) return CU::UNWIND_MODE_DWARF;
576
577 // Encode the register encoding.
578 CompactUnwindEncoding |=
579 RegEnc & CU::UNWIND_FRAMELESS_STACK_REG_PERMUTATION;
580 }
581
582 return CompactUnwindEncoding;
583 }
584
585 private:
586 /// \brief Get the compact unwind number for a given register. The number
587 /// corresponds to the enum lists in compact_unwind_encoding.h.
588 int getCompactUnwindRegNum(unsigned Reg) const {
589 static const uint16_t CU32BitRegs[7] = {
590 X86::EBX, X86::ECX, X86::EDX, X86::EDI, X86::ESI, X86::EBP, 0
591 };
592 static const uint16_t CU64BitRegs[] = {
593 X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0
594 };
595 const uint16_t *CURegs = Is64Bit ? CU64BitRegs : CU32BitRegs;
596 for (int Idx = 1; *CURegs; ++CURegs, ++Idx)
597 if (*CURegs == Reg)
598 return Idx;
599
600 return -1;
601 }
602
603 /// \brief Return the registers encoded for a compact encoding with a frame
604 /// pointer.
605 uint32_t encodeCompactUnwindRegistersWithFrame() const {
606 // Encode the registers in the order they were saved --- 3-bits per
607 // register. The list of saved registers is assumed to be in reverse
608 // order. The registers are numbered from 1 to CU_NUM_SAVED_REGS.
609 uint32_t RegEnc = 0;
610 for (int i = 0, Idx = 0; i != CU_NUM_SAVED_REGS; ++i) {
611 unsigned Reg = SavedRegs[i];
612 if (Reg == 0) break;
613
614 int CURegNum = getCompactUnwindRegNum(Reg);
615 if (CURegNum == -1) return ~0U;
616
617 // Encode the 3-bit register number in order, skipping over 3-bits for
618 // each register.
619 RegEnc |= (CURegNum & 0x7) << (Idx++ * 3);
620 }
621
622 assert((RegEnc & 0x3FFFF) == RegEnc &&
623 "Invalid compact register encoding!");
624 return RegEnc;
625 }
626
627 /// \brief Create the permutation encoding used with frameless stacks. It is
628 /// passed the number of registers to be saved and an array of the registers
629 /// saved.
630 uint32_t encodeCompactUnwindRegistersWithoutFrame(unsigned RegCount) const {
631 // The saved registers are numbered from 1 to 6. In order to encode the
632 // order in which they were saved, we re-number them according to their
633 // place in the register order. The re-numbering is relative to the last
634 // re-numbered register. E.g., if we have registers {6, 2, 4, 5} saved in
635 // that order:
636 //
637 // Orig Re-Num
638 // ---- ------
639 // 6 6
640 // 2 2
641 // 4 3
642 // 5 3
643 //
644 for (unsigned i = 0; i != CU_NUM_SAVED_REGS; ++i) {
645 int CUReg = getCompactUnwindRegNum(SavedRegs[i]);
646 if (CUReg == -1) return ~0U;
647 SavedRegs[i] = CUReg;
648 }
649
650 // Reverse the list.
651 std::reverse(&SavedRegs[0], &SavedRegs[CU_NUM_SAVED_REGS]);
652
653 uint32_t RenumRegs[CU_NUM_SAVED_REGS];
654 for (unsigned i = CU_NUM_SAVED_REGS - RegCount; i < CU_NUM_SAVED_REGS; ++i){
655 unsigned Countless = 0;
656 for (unsigned j = CU_NUM_SAVED_REGS - RegCount; j < i; ++j)
657 if (SavedRegs[j] < SavedRegs[i])
658 ++Countless;
659
660 RenumRegs[i] = SavedRegs[i] - Countless - 1;
661 }
662
663 // Take the renumbered values and encode them into a 10-bit number.
664 uint32_t permutationEncoding = 0;
665 switch (RegCount) {
666 case 6:
667 permutationEncoding |= 120 * RenumRegs[0] + 24 * RenumRegs[1]
668 + 6 * RenumRegs[2] + 2 * RenumRegs[3]
669 + RenumRegs[4];
670 break;
671 case 5:
672 permutationEncoding |= 120 * RenumRegs[1] + 24 * RenumRegs[2]
673 + 6 * RenumRegs[3] + 2 * RenumRegs[4]
674 + RenumRegs[5];
675 break;
676 case 4:
677 permutationEncoding |= 60 * RenumRegs[2] + 12 * RenumRegs[3]
678 + 3 * RenumRegs[4] + RenumRegs[5];
679 break;
680 case 3:
681 permutationEncoding |= 20 * RenumRegs[3] + 4 * RenumRegs[4]
682 + RenumRegs[5];
683 break;
684 case 2:
685 permutationEncoding |= 5 * RenumRegs[4] + RenumRegs[5];
686 break;
687 case 1:
688 permutationEncoding |= RenumRegs[5];
689 break;
690 }
691
692 assert((permutationEncoding & 0x3FF) == permutationEncoding &&
693 "Invalid compact register encoding!");
694 return permutationEncoding;
695 }
696
385697 public:
386 DarwinX86AsmBackend(const Target &T, StringRef CPU)
387 : X86AsmBackend(T, CPU) { }
698 DarwinX86AsmBackend(const Target &T, const MCRegisterInfo &MRI, StringRef CPU,
699 bool Is64Bit)
700 : X86AsmBackend(T, CPU), MRI(MRI), Is64Bit(Is64Bit) {
701 memset(SavedRegs, 0, sizeof(SavedRegs));
702 OffsetSize = Is64Bit ? 8 : 4;
703 MoveInstrSize = Is64Bit ? 3 : 2;
704 StackDivide = Is64Bit ? 8 : 4;
705 PushInstrSize = 1;
706 }
388707 };
389708
390709 class DarwinX86_32AsmBackend : public DarwinX86AsmBackend {
710 bool SupportsCU;
391711 public:
392 DarwinX86_32AsmBackend(const Target &T, StringRef CPU)
393 : DarwinX86AsmBackend(T, CPU) {}
712 DarwinX86_32AsmBackend(const Target &T, const MCRegisterInfo &MRI,
713 StringRef CPU, bool SupportsCU)
714 : DarwinX86AsmBackend(T, MRI, CPU, false), SupportsCU(SupportsCU) {}
394715
395716 MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
396717 return createX86MachObjectWriter(OS, /*Is64Bit=*/false,
397718 MachO::CPU_TYPE_I386,
398719 MachO::CPU_SUBTYPE_I386_ALL);
399720 }
721
722 /// \brief Generate the compact unwind encoding for the CFI instructions.
723 virtual unsigned
724 generateCompactUnwindEncoding(ArrayRef Instrs) const {
725 return SupportsCU ? generateCompactUnwindEncodingImpl(Instrs) : 0;
726 }
400727 };
401728
402729 class DarwinX86_64AsmBackend : public DarwinX86AsmBackend {
730 bool SupportsCU;
403731 public:
404 DarwinX86_64AsmBackend(const Target &T, StringRef CPU)
405 : DarwinX86AsmBackend(T, CPU) {
732 DarwinX86_64AsmBackend(const Target &T, const MCRegisterInfo &MRI,
733 StringRef CPU, bool SupportsCU)
734 : DarwinX86AsmBackend(T, MRI, CPU, true), SupportsCU(SupportsCU) {
406735 HasReliableSymbolDifference = true;
407736 }
408737
444773 return false;
445774 }
446775 }
776
777 /// \brief Generate the compact unwind encoding for the CFI instructions.
778 virtual unsigned
779 generateCompactUnwindEncoding(ArrayRef Instrs) const {
780 return SupportsCU ? generateCompactUnwindEncodingImpl(Instrs) : 0;
781 }
447782 };
448783
449784 } // end anonymous namespace
450785
451 MCAsmBackend *llvm::createX86_32AsmBackend(const Target &T, StringRef TT, StringRef CPU) {
786 MCAsmBackend *llvm::createX86_32AsmBackend(const Target &T,
787 const MCRegisterInfo &MRI,
788 StringRef TT,
789 StringRef CPU) {
452790 Triple TheTriple(TT);
453791
454792 if (TheTriple.isOSDarwin() || TheTriple.getEnvironment() == Triple::MachO)
455 return new DarwinX86_32AsmBackend(T, CPU);
793 return new DarwinX86_32AsmBackend(T, MRI, CPU,
794 TheTriple.isMacOSX() &&
795 !TheTriple.isMacOSXVersionLT(10, 7));
456796
457797 if (TheTriple.isOSWindows() && TheTriple.getEnvironment() != Triple::ELF)
458798 return new WindowsX86AsmBackend(T, false, CPU);
461801 return new ELFX86_32AsmBackend(T, OSABI, CPU);
462802 }
463803
464 MCAsmBackend *llvm::createX86_64AsmBackend(const Target &T, StringRef TT, StringRef CPU) {
804 MCAsmBackend *llvm::createX86_64AsmBackend(const Target &T,
805 const MCRegisterInfo &MRI,
806 StringRef TT,
807 StringRef CPU) {
465808 Triple TheTriple(TT);
466809
467810 if (TheTriple.isOSDarwin() || TheTriple.getEnvironment() == Triple::MachO)
468 return new DarwinX86_64AsmBackend(T, CPU);
811 return new DarwinX86_64AsmBackend(T, MRI, CPU,
812 TheTriple.isMacOSX() &&
813 !TheTriple.isMacOSXVersionLT(10, 7));
469814
470815 if (TheTriple.isOSWindows() && TheTriple.getEnvironment() != Triple::ELF)
471816 return new WindowsX86AsmBackend(T, true, CPU);
7878 const MCSubtargetInfo &STI,
7979 MCContext &Ctx);
8080
81 MCAsmBackend *createX86_32AsmBackend(const Target &T, StringRef TT, StringRef CPU);
82 MCAsmBackend *createX86_64AsmBackend(const Target &T, StringRef TT, StringRef CPU);
81 MCAsmBackend *createX86_32AsmBackend(const Target &T, const MCRegisterInfo &MRI,
82 StringRef TT, StringRef CPU);
83 MCAsmBackend *createX86_64AsmBackend(const Target &T, const MCRegisterInfo &MRI,
84 StringRef TT, StringRef CPU);
8385
8486 /// createX86MachObjectWriter - Construct an X86 Mach-O object writer.
8587 MCObjectWriter *createX86MachObjectWriter(raw_ostream &OS,
362362 unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true);
363363 MMI.addFrameInst(MCCFIInstruction::createOffset(Label, DwarfReg, Offset));
364364 }
365 }
366
367 /// getCompactUnwindRegNum - Get the compact unwind number for a given
368 /// register. The number corresponds to the enum lists in
369 /// compact_unwind_encoding.h.
370 static int getCompactUnwindRegNum(unsigned Reg, bool is64Bit) {
371 static const uint16_t CU32BitRegs[] = {
372 X86::EBX, X86::ECX, X86::EDX, X86::EDI, X86::ESI, X86::EBP, 0
373 };
374 static const uint16_t CU64BitRegs[] = {
375 X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0
376 };
377 const uint16_t *CURegs = is64Bit ? CU64BitRegs : CU32BitRegs;
378 for (int Idx = 1; *CURegs; ++CURegs, ++Idx)
379 if (*CURegs == Reg)
380 return Idx;
381
382 return -1;
383 }
384
385 // Number of registers that can be saved in a compact unwind encoding.
386 #define CU_NUM_SAVED_REGS 6
387
388 /// encodeCompactUnwindRegistersWithoutFrame - Create the permutation encoding
389 /// used with frameless stacks. It is passed the number of registers to be saved
390 /// and an array of the registers saved.
391 static uint32_t
392 encodeCompactUnwindRegistersWithoutFrame(unsigned SavedRegs[CU_NUM_SAVED_REGS],
393 unsigned RegCount, bool Is64Bit) {
394 // The saved registers are numbered from 1 to 6. In order to encode the order
395 // in which they were saved, we re-number them according to their place in the
396 // register order. The re-numbering is relative to the last re-numbered
397 // register. E.g., if we have registers {6, 2, 4, 5} saved in that order:
398 //
399 // Orig Re-Num
400 // ---- ------
401 // 6 6
402 // 2 2
403 // 4 3
404 // 5 3
405 //
406 for (unsigned i = 0; i != CU_NUM_SAVED_REGS; ++i) {
407 int CUReg = getCompactUnwindRegNum(SavedRegs[i], Is64Bit);
408 if (CUReg == -1) return ~0U;
409 SavedRegs[i] = CUReg;
410 }
411
412 // Reverse the list.
413 std::swap(SavedRegs[0], SavedRegs[5]);
414 std::swap(SavedRegs[1], SavedRegs[4]);
415 std::swap(SavedRegs[2], SavedRegs[3]);
416
417 uint32_t RenumRegs[CU_NUM_SAVED_REGS];
418 for (unsigned i = CU_NUM_SAVED_REGS - RegCount; i < CU_NUM_SAVED_REGS; ++i) {
419 unsigned Countless = 0;
420 for (unsigned j = CU_NUM_SAVED_REGS - RegCount; j < i; ++j)
421 if (SavedRegs[j] < SavedRegs[i])
422 ++Countless;
423
424 RenumRegs[i] = SavedRegs[i] - Countless - 1;
425 }
426
427 // Take the renumbered values and encode them into a 10-bit number.
428 uint32_t permutationEncoding = 0;
429 switch (RegCount) {
430 case 6:
431 permutationEncoding |= 120 * RenumRegs[0] + 24 * RenumRegs[1]
432 + 6 * RenumRegs[2] + 2 * RenumRegs[3]
433 + RenumRegs[4];
434 break;
435 case 5:
436 permutationEncoding |= 120 * RenumRegs[1] + 24 * RenumRegs[2]
437 + 6 * RenumRegs[3] + 2 * RenumRegs[4]
438 + RenumRegs[5];
439 break;
440 case 4:
441 permutationEncoding |= 60 * RenumRegs[2] + 12 * RenumRegs[3]
442 + 3 * RenumRegs[4] + RenumRegs[5];
443 break;
444 case 3:
445 permutationEncoding |= 20 * RenumRegs[3] + 4 * RenumRegs[4]
446 + RenumRegs[5];
447 break;
448 case 2:
449 permutationEncoding |= 5 * RenumRegs[4] + RenumRegs[5];
450 break;
451 case 1:
452 permutationEncoding |= RenumRegs[5];
453 break;
454 }
455
456 assert((permutationEncoding & 0x3FF) == permutationEncoding &&
457 "Invalid compact register encoding!");
458 return permutationEncoding;
459 }
460
461 /// encodeCompactUnwindRegistersWithFrame - Return the registers encoded for a
462 /// compact encoding with a frame pointer.
463 static uint32_t
464 encodeCompactUnwindRegistersWithFrame(unsigned SavedRegs[CU_NUM_SAVED_REGS],
465 bool Is64Bit) {
466 // Encode the registers in the order they were saved, 3-bits per register. The
467 // registers are numbered from 1 to CU_NUM_SAVED_REGS.
468 uint32_t RegEnc = 0;
469 for (int I = CU_NUM_SAVED_REGS - 1, Idx = 0; I != -1; --I) {
470 unsigned Reg = SavedRegs[I];
471 if (Reg == 0) continue;
472
473 int CURegNum = getCompactUnwindRegNum(Reg, Is64Bit);
474 if (CURegNum == -1) return ~0U;
475
476 // Encode the 3-bit register number in order, skipping over 3-bits for each
477 // register.
478 RegEnc |= (CURegNum & 0x7) << (Idx++ * 3);
479 }
480
481 assert((RegEnc & 0x3FFFF) == RegEnc && "Invalid compact register encoding!");
482 return RegEnc;
483 }
484
485 static uint32_t
486 doCompactUnwindEncoding(unsigned SavedRegs[CU_NUM_SAVED_REGS],
487 unsigned StackSize, unsigned StackAdjust,
488 unsigned SubtractInstrIdx, unsigned SavedRegIdx,
489 bool Is64Bit, bool HasFP) {
490 // Encode that we are using EBP/RBP as the frame pointer.
491 unsigned StackDivide = (Is64Bit ? 8 : 4);
492 uint32_t CompactUnwindEncoding = 0;
493
494 StackAdjust /= StackDivide;
495
496 if (HasFP) {
497 if ((StackAdjust & 0xFF) != StackAdjust)
498 // Offset was too big for compact encoding.
499 return CU::UNWIND_MODE_DWARF;
500
501 // Get the encoding of the saved registers when we have a frame pointer.
502 uint32_t RegEnc = encodeCompactUnwindRegistersWithFrame(SavedRegs, Is64Bit);
503 if (RegEnc == ~0U) return CU::UNWIND_MODE_DWARF;
504
505 CompactUnwindEncoding |= CU::UNWIND_MODE_BP_FRAME;
506 CompactUnwindEncoding |= (StackAdjust & 0xFF) << 16;
507 CompactUnwindEncoding |= RegEnc & CU::UNWIND_BP_FRAME_REGISTERS;
508 } else {
509 ++StackAdjust;
510 uint32_t TotalStackSize = StackAdjust + StackSize;
511 if ((TotalStackSize & 0xFF) == TotalStackSize) {
512 // Frameless stack with a small stack size.
513 CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IMMD;
514
515 // Encode the stack size.
516 CompactUnwindEncoding |= (TotalStackSize & 0xFF) << 16;
517 } else {
518 if ((StackAdjust & 0x7) != StackAdjust)
519 // The extra stack adjustments are too big for us to handle.
520 return CU::UNWIND_MODE_DWARF;
521
522 // Frameless stack with an offset too large for us to encode compactly.
523 CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IND;
524
525 // Encode the offset to the nnnnnn value in the 'subl $nnnnnn, ESP'
526 // instruction.
527 CompactUnwindEncoding |= (SubtractInstrIdx & 0xFF) << 16;
528
529 // Encode any extra stack stack adjustments (done via push instructions).
530 CompactUnwindEncoding |= (StackAdjust & 0x7) << 13;
531 }
532
533 // Encode the number of registers saved.
534 CompactUnwindEncoding |= (SavedRegIdx & 0x7) << 10;
535
536 // Get the encoding of the saved registers when we don't have a frame
537 // pointer.
538 uint32_t RegEnc =
539 encodeCompactUnwindRegistersWithoutFrame(SavedRegs, SavedRegIdx,
540 Is64Bit);
541 if (RegEnc == ~0U) return CU::UNWIND_MODE_DWARF;
542
543 // Encode the register encoding.
544 CompactUnwindEncoding |=
545 RegEnc & CU::UNWIND_FRAMELESS_STACK_REG_PERMUTATION;
546 }
547
548 return CompactUnwindEncoding;
549 }
550
551 uint32_t X86FrameLowering::getCompactUnwindEncoding(MachineFunction &MF) const {
552 const X86RegisterInfo *RegInfo = TM.getRegisterInfo();
553 unsigned FramePtr = RegInfo->getFrameRegister(MF);
554 unsigned StackPtr = RegInfo->getStackRegister();
555
556 bool Is64Bit = STI.is64Bit();
557
558 unsigned SavedRegs[CU_NUM_SAVED_REGS] = { 0, 0, 0, 0, 0, 0 };
559 unsigned SavedRegIdx = 0;
560
561 unsigned OffsetSize = (Is64Bit ? 8 : 4);
562
563 unsigned PushInstr = (Is64Bit ? X86::PUSH64r : X86::PUSH32r);
564 unsigned PushInstrSize = 1;
565 unsigned MoveInstr = (Is64Bit ? X86::MOV64rr : X86::MOV32rr);
566 unsigned MoveInstrSize = (Is64Bit ? 3 : 2);
567 unsigned SubtractInstrIdx = (Is64Bit ? 3 : 2);
568
569 unsigned StackDivide = (Is64Bit ? 8 : 4);
570
571 unsigned InstrOffset = 0;
572 unsigned StackAdjust = 0;
573 unsigned StackSize = 0;
574
575 bool ExpectEnd = false;
576 for (MachineBasicBlock::iterator MBBI = MF.front().begin(),
577 MBBE = MF.front().end(); MBBI != MBBE; ++MBBI) {
578 MachineInstr &MI = *MBBI;
579 unsigned Opc = MI.getOpcode();
580 if (Opc == X86::PROLOG_LABEL) continue;
581 if (!MI.getFlag(MachineInstr::FrameSetup)) break;
582
583 // We don't exect any more prolog instructions.
584 if (ExpectEnd) return CU::UNWIND_MODE_DWARF;
585
586 if (Opc == PushInstr) {
587 // If there are too many saved registers, we cannot use compact encoding.
588 if (SavedRegIdx >= CU_NUM_SAVED_REGS) return CU::UNWIND_MODE_DWARF;
589
590 unsigned Reg = MI.getOperand(0).getReg();
591 if (Reg == (Is64Bit ? X86::RAX : X86::EAX)) {
592 ExpectEnd = true;
593 continue;
594 }
595
596 SavedRegs[SavedRegIdx++] = MI.getOperand(0).getReg();
597 StackAdjust += OffsetSize;
598 InstrOffset += PushInstrSize;
599 } else if (Opc == MoveInstr) {
600 unsigned SrcReg = MI.getOperand(1).getReg();
601 unsigned DstReg = MI.getOperand(0).getReg();
602
603 if (DstReg != FramePtr || SrcReg != StackPtr)
604 return CU::UNWIND_MODE_DWARF;
605
606 StackAdjust = 0;
607 memset(SavedRegs, 0, sizeof(SavedRegs));
608 SavedRegIdx = 0;
609 InstrOffset += MoveInstrSize;
610 } else if (Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 ||
611 Opc == X86::SUB32ri || Opc == X86::SUB32ri8) {
612 if (StackSize)
613 // We already have a stack size.
614 return CU::UNWIND_MODE_DWARF;
615
616 if (!MI.getOperand(0).isReg() ||
617 MI.getOperand(0).getReg() != MI.getOperand(1).getReg() ||
618 MI.getOperand(0).getReg() != StackPtr || !MI.getOperand(2).isImm())
619 // We need this to be a stack adjustment pointer. Something like:
620 //
621 // %RSP = SUB64ri8 %RSP, 48
622 return CU::UNWIND_MODE_DWARF;
623
624 StackSize = MI.getOperand(2).getImm() / StackDivide;
625 SubtractInstrIdx += InstrOffset;
626 ExpectEnd = true;
627 }
628 }
629
630 return doCompactUnwindEncoding(SavedRegs, StackSize, StackAdjust,
631 SubtractInstrIdx, SavedRegIdx,
632 Is64Bit, hasFP(MF));
633365 }
634366
635367 /// usesTheStack - This function checks if any of the users of EFLAGS
974706 if (PushedRegs)
975707 emitCalleeSavedFrameMoves(MF, Label, HasFP ? FramePtr : StackPtr);
976708 }
977
978 // Darwin 10.7 and greater has support for compact unwind encoding.
979 if (STI.getTargetTriple().isMacOSX() &&
980 !STI.getTargetTriple().isMacOSXVersionLT(10, 7))
981 MMI.setCompactUnwindEncoding(getCompactUnwindEncoding(MF));
982709 }
983710
984711 void X86FrameLowering::emitEpilogue(MachineFunction &MF,
1818 #include "llvm/Target/TargetFrameLowering.h"
1919
2020 namespace llvm {
21
22 namespace CU {
23
24 /// Compact unwind encoding values.
25 enum CompactUnwindEncodings {
26 /// [RE]BP based frame where [RE]BP is pused on the stack immediately after
27 /// the return address, then [RE]SP is moved to [RE]BP.
28 UNWIND_MODE_BP_FRAME = 0x01000000,
29
30 /// A frameless function with a small constant stack size.
31 UNWIND_MODE_STACK_IMMD = 0x02000000,
32
33 /// A frameless function with a large constant stack size.
34 UNWIND_MODE_STACK_IND = 0x03000000,
35
36 /// No compact unwind encoding is available.
37 UNWIND_MODE_DWARF = 0x04000000,
38
39 /// Mask for encoding the frame registers.
40 UNWIND_BP_FRAME_REGISTERS = 0x00007FFF,
41
42 /// Mask for encoding the frameless registers.
43 UNWIND_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF
44 };
45
46 } // end CU namespace
4721
4822 class MCSymbol;
4923 class X86TargetMachine;
9064 int getFrameIndexOffset(const MachineFunction &MF, int FI) const;
9165 int getFrameIndexReference(const MachineFunction &MF, int FI,
9266 unsigned &FrameReg) const;
93 uint32_t getCompactUnwindEncoding(MachineFunction &MF) const;
9467
9568 void eliminateCallFramePseudoInstr(MachineFunction &MF,
9669 MachineBasicBlock &MBB,
None ; RUN: llc < %s -disable-cfi -disable-fp-elim -mtriple x86_64-apple-darwin11 | FileCheck %s
0 ; RUN: llc < %s -disable-fp-elim -mtriple x86_64-apple-darwin11 | FileCheck -check-prefix=ASM %s
1 ; RUN: llc < %s -disable-fp-elim -mtriple x86_64-apple-darwin11 -filetype=obj -o - \
2 ; RUN: | llvm-objdump -triple x86_64-apple-darwin11 -s - \
3 ; RUN: | FileCheck -check-prefix=CU %s
14
25 %ty = type { i8* }
36
47 @gv = external global i32
58
69 ; This is aligning the stack with a push of a random register.
7 ; CHECK: pushq %rax
10 ; ASM: pushq %rax
811
912 ; Even though we can't encode %rax into the compact unwind, We still want to be
1013 ; able to generate a compact unwind encoding in this particular case.
1114 ;
12 ; CHECK: __LD,__compact_unwind
13 ; CHECK: _foo ## Range Start
14 ; CHECK: 16842753 ## Compact Unwind Encoding: 0x1010001
15 ; CU: Contents of section __compact_unwind:
16 ; CU-NEXT: 0020 00000000 00000000 1e000000 01000101
17 ; CU-NEXT: 0030 00000000 00000000 00000000 00000000
1518
1619 define i8* @foo(i64 %size) {
1720 %addr = alloca i64, align 8
None ; RUN: llc < %s -mtriple x86_64-apple-macosx10.8.0 -disable-cfi | FileCheck %s
0 ; RUN: llc < %s -mtriple x86_64-apple-macosx10.8.0 -filetype=obj -o - \
1 ; RUN: | llvm-objdump -triple x86_64-apple-macosx10.8.0 -s - \
2 ; RUN: | FileCheck %s
13
24 %"struct.dyld::MappedRanges" = type { [400 x %struct.anon], %"struct.dyld::MappedRanges"* }
35 %struct.anon = type { %class.ImageLoader*, i64, i64 }
1214 ; compact unwind encodings for this function. This then defaults to using the
1315 ; DWARF EH frame.
1416 ;
15 ; CHECK: .section __LD,__compact_unwind,regular,debug
16 ; CHECK: .quad _func
17 ; CHECK: .long 67108864 ## Compact Unwind Encoding: 0x4000000
18 ; CHECK: .quad 0 ## Personality Function
19 ; CHECK: .quad 0 ## LSDA
17 ; CHECK: Contents of section __compact_unwind:
18 ; CHECK-NEXT: 0048 00000000 00000000 42000000 00000004
19 ; CHECK-NEXT: 0058 00000000 00000000 00000000 00000000
2020 ;
21
2122 define void @func(%class.ImageLoader* %image) optsize ssp uwtable {
2223 entry:
2324 br label %for.cond1.preheader
431431 MCAsmBackend *MAB = 0;
432432 if (ShowEncoding) {
433433 CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
434 MAB = TheTarget->createMCAsmBackend(TripleName, MCPU);
434 MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU);
435435 }
436436 bool UseCFI = !DisableCFI;
437437 Str.reset(TheTarget->createAsmStreamer(Ctx, FOS, /*asmverbose*/true,
445445 } else {
446446 assert(FileType == OFT_ObjectFile && "Invalid file type!");
447447 MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
448 MCAsmBackend *MAB = TheTarget->createMCAsmBackend(TripleName, MCPU);
448 MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU);
449449 Str.reset(TheTarget->createMCObjectStreamer(TripleName, Ctx, *MAB,
450450 FOS, CE, RelaxAll,
451451 NoExecStack));