Index: lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp =================================================================== --- lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp +++ lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp @@ -212,6 +212,9 @@ case MCCFIInstruction::OpEscape: OutStreamer->EmitCFIEscape(Inst.getValues()); break; + case MCCFIInstruction::OpRestore: + OutStreamer->EmitCFIRestore(Inst.getRegister()); + break; } } Index: lib/CodeGen/MIRParser/MILexer.h =================================================================== --- lib/CodeGen/MIRParser/MILexer.h +++ lib/CodeGen/MIRParser/MILexer.h @@ -68,6 +68,7 @@ kw_cfi_def_cfa_register, kw_cfi_def_cfa_offset, kw_cfi_def_cfa, + kw_cfi_restore, kw_blockaddress, kw_intrinsic, kw_target_index, Index: lib/CodeGen/MIRParser/MILexer.cpp =================================================================== --- lib/CodeGen/MIRParser/MILexer.cpp +++ lib/CodeGen/MIRParser/MILexer.cpp @@ -210,6 +210,7 @@ .Case("def_cfa_register", MIToken::kw_cfi_def_cfa_register) .Case("def_cfa_offset", MIToken::kw_cfi_def_cfa_offset) .Case("def_cfa", MIToken::kw_cfi_def_cfa) + .Case("restore", MIToken::kw_cfi_restore) .Case("blockaddress", MIToken::kw_blockaddress) .Case("intrinsic", MIToken::kw_intrinsic) .Case("target-index", MIToken::kw_target_index) Index: lib/CodeGen/MIRParser/MIParser.cpp =================================================================== --- lib/CodeGen/MIRParser/MIParser.cpp +++ lib/CodeGen/MIRParser/MIParser.cpp @@ -1581,6 +1581,12 @@ CFIIndex = MF.addFrameInst(MCCFIInstruction::createDefCfa(nullptr, Reg, -Offset)); break; + case MIToken::kw_cfi_restore: + if (parseCFIRegister(Reg)) + return true; + CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore(nullptr, Reg)); + break; + default: // TODO: Parse the other CFI operands. llvm_unreachable("The current token should be a cfi operand"); @@ -1858,6 +1864,7 @@ case MIToken::kw_cfi_def_cfa_register: case MIToken::kw_cfi_def_cfa_offset: case MIToken::kw_cfi_def_cfa: + case MIToken::kw_cfi_restore: return parseCFIOperand(Dest); case MIToken::kw_blockaddress: return parseBlockAddressOperand(Dest); Index: lib/CodeGen/MIRPrinter.cpp =================================================================== --- lib/CodeGen/MIRPrinter.cpp +++ lib/CodeGen/MIRPrinter.cpp @@ -1208,6 +1208,12 @@ printCFIRegister(CFI.getRegister(), OS, TRI); OS << ", " << CFI.getOffset(); break; + case MCCFIInstruction::OpRestore: + OS << "restore "; + if (CFI.getLabel()) + OS << " "; + printCFIRegister(CFI.getRegister(), OS, TRI); + break; default: // TODO: Print the other CFI Operations. OS << ""; Index: lib/MC/MCAsmStreamer.cpp =================================================================== --- lib/MC/MCAsmStreamer.cpp +++ lib/MC/MCAsmStreamer.cpp @@ -256,6 +256,7 @@ void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) override; void EmitCFIRememberState() override; void EmitCFIRestoreState() override; + void EmitCFIRestore(int64_t Register) override; void EmitCFISameValue(int64_t Register) override; void EmitCFIRelOffset(int64_t Register, int64_t Offset) override; void EmitCFIAdjustCfaOffset(int64_t Adjustment) override; @@ -1353,6 +1354,13 @@ EmitEOL(); } +void MCAsmStreamer::EmitCFIRestore(int64_t Register) { + MCStreamer::EmitCFIRestore(Register); + OS << "\t.cfi_restore "; + EmitRegisterName(Register); + EmitEOL(); +} + void MCAsmStreamer::EmitCFISameValue(int64_t Register) { MCStreamer::EmitCFISameValue(Register); OS << "\t.cfi_same_value "; Index: test/CodeGen/AArch64/cfi_restore.mir =================================================================== --- /dev/null +++ test/CodeGen/AArch64/cfi_restore.mir @@ -0,0 +1,37 @@ +# RUN: llc -mtriple=aarch64-- -start-after prologepilog -o - %s | FileCheck %s +--- +name: fun +# CHECK: .cfi_startproc +tracksRegLiveness: true +frameInfo: + stackSize: 16 + maxAlignment: 8 + hasCalls: true +stack: + - { id: 0, type: spill-slot, offset: -8, size: 8, alignment: 8, stack-id: 0, + callee-saved-register: '%lr' } + - { id: 1, type: spill-slot, offset: -16, size: 8, alignment: 8, stack-id: 0, + callee-saved-register: '%fp' } +body: | + bb.0: + liveins: %fp, %lr + + %sp = frame-setup SUBXri %sp, 16, 0 + frame-setup STRXui killed %fp, %sp, 0 :: (store 8 into %stack.1) + frame-setup CFI_INSTRUCTION offset %w29, -16 + ; CHECK: .cfi_offset w29, -16 + frame-setup STRXui killed %lr, %sp, 1 :: (store 8 into %stack.0) + frame-setup CFI_INSTRUCTION offset %w30, -8 + ; CHECK: .cfi_offset w30, -8 + %fp = frame-setup ADDXri %sp, 0, 0 + frame-setup CFI_INSTRUCTION def_cfa %w29, 16 + %lr = LDRXui %sp, 1 :: (load 8 from %stack.0) + CFI_INSTRUCTION restore %w30 + ; CHECK: .cfi_restore w30 + %fp = LDRXui %sp, 0 :: (load 8 from %stack.1) + CFI_INSTRUCTION restore %w29 + ; CHECK: .cfi_restore w29 + %sp = ADDXri %sp, 16, 0 + RET_ReallyLR + ; CHECK: .cfi_endproc +... Index: test/CodeGen/MIR/AArch64/cfi-def-cfa.mir =================================================================== --- test/CodeGen/MIR/AArch64/cfi-def-cfa.mir +++ /dev/null @@ -1,31 +0,0 @@ -# RUN: llc -mtriple=aarch64-none-linux-gnu -run-pass none -o - %s | FileCheck %s -# This test ensures that the MIR parser parses the def_cfa operands -# correctly. - ---- | - - declare void @foo() - - define void @trivial_fp_func() { - entry: - call void @foo() - ret void - } - -... ---- -name: trivial_fp_func -body: | - bb.0.entry: - liveins: %lr, %fp, %lr, %fp - - %sp = frame-setup STPXpre killed %fp, killed %lr, %sp, -2 - %fp = frame-setup ADDXri %sp, 0, 0 - ; CHECK: CFI_INSTRUCTION def_cfa %w29, 16 - frame-setup CFI_INSTRUCTION def_cfa %w29, 16 - frame-setup CFI_INSTRUCTION offset %w30, -8 - frame-setup CFI_INSTRUCTION offset %w29, -16 - BL @foo, csr_aarch64_aapcs, implicit-def dead %lr, implicit %sp, implicit-def %sp - %sp, %fp, %lr = LDPXpost %sp, 2 - RET_ReallyLR -... Index: test/CodeGen/MIR/AArch64/cfi.mir =================================================================== --- /dev/null +++ test/CodeGen/MIR/AArch64/cfi.mir @@ -0,0 +1,59 @@ +# RUN: llc -mtriple=aarch64-none-linux-gnu -run-pass none -o - %s | FileCheck %s +# This test ensures that the MIR parser parses the cfi directives correctly. + +--- | + + declare void @foo() + + define void @trivial_fp_func() { + entry: + call void @foo() + ret void + } + + define void @trivial_fp_func_restore() { + entry: + call void @foo() + ret void + } + +... +--- +name: trivial_fp_func +# CHECK-LABEL: name: trivial_fp_func +body: | + bb.0.entry: + liveins: %lr, %fp, %lr, %fp + + %sp = frame-setup STPXpre killed %fp, killed %lr, %sp, -2 + %fp = frame-setup ADDXri %sp, 0, 0 + ; CHECK: CFI_INSTRUCTION def_cfa %w29, 16 + frame-setup CFI_INSTRUCTION def_cfa %w29, 16 + frame-setup CFI_INSTRUCTION offset %w30, -8 + frame-setup CFI_INSTRUCTION offset %w29, -16 + BL @foo, csr_aarch64_aapcs, implicit-def dead %lr, implicit %sp, implicit-def %sp + %sp, %fp, %lr = LDPXpost %sp, 2 + RET_ReallyLR +... +--- +name: trivial_fp_func_restore +# CHECK-LABEL: name: trivial_fp_func_restore +body: | + bb.0.entry: + liveins: %lr, %fp + + %sp = frame-setup STPXpre killed %fp, killed %lr, %sp, -2 + %fp = frame-setup ADDXri %sp, 0, 0 + frame-setup CFI_INSTRUCTION def_cfa %w29, 16 + frame-setup CFI_INSTRUCTION offset %w30, -8 + ; CHECK: CFI_INSTRUCTION offset %w30, -8 + frame-setup CFI_INSTRUCTION offset %w29, -16 + ; CHECK: CFI_INSTRUCTION offset %w29, -16 + BL @foo, csr_aarch64_aapcs, implicit-def dead %lr, implicit %sp, implicit-def %sp + %sp, %fp, %lr = LDPXpost %sp, 2 + CFI_INSTRUCTION restore %w30 + ; CHECK: CFI_INSTRUCTION restore %w30 + CFI_INSTRUCTION restore %w29 + ; CHECK: CFI_INSTRUCTION restore %w29 + RET_ReallyLR +... Index: test/MC/AArch64/cfi.s =================================================================== --- /dev/null +++ test/MC/AArch64/cfi.s @@ -0,0 +1,26 @@ +// RUN: llvm-mc -triple aarch64-- -o - %s | FileCheck %s + +fun: + .cfi_startproc +// CHECK: .cfi_startproc + stp x29, x30, [sp, #-16]! +.Lcfi0: + .cfi_offset w29, -16 +// CHECK: .cfi_offset w29, -16 +.Lcfi1: + .cfi_offset w30, -8 +// CHECK: .cfi_offset w30, -8 + mov x29, sp +.Lcfi2: + .cfi_def_cfa w29, 16 +// CHECK: .cfi_def_cfa w29, 16 +.Lcfi3: + .cfi_restore w30 +// CHECK: .cfi_restore w30 + ldr x29, [sp], #16 +.Lcfi4: + .cfi_restore w29 +// CHECK: .cfi_restore w29 + ret + .cfi_endproc +// CHECK: .cfi_endproc