This ensures that you get the same output regardless if generating code directly to an object file or if generating assembly and assembling that. Add implementations of the EmitARM64WinCFI*() methods in AArch64TargetAsmStreamer, and fill in one blank in MCAsmStreamer. Add corresponding directive handlers in AArch64AsmParser and COFFAsmParser. Some SEH directive names have been picked to match the prior art for SEH assembly directives for x86_64, e.g. the spelling of ".seh_startepilogue" matching the preexisting ".seh_endprologue". For the directives for saving registers, the exact spelling from the arm64 documentation is picked, e.g. ".seh_save_reg" (to follow that naming for all the other ones, e.g. ".seh_save_fregp_x"), while the corresponding one for x86_64 is plain ".seh_savereg" without the second underscore. Directives in the epilogues have the same names as in prologues, e.g. .seh_savereg, even though the registers are restored, not saved, at that point. Differential Revision: https://reviews.llvm.org/D86529
33 lines
927 B
LLVM
33 lines
927 B
LLVM
; RUN: llc -mtriple aarch64-windows -filetype asm -o - < %s | FileCheck %s
|
|
; RUN: llc -mtriple aarch64-windows -filetype asm -o - -fast-isel %s | FileCheck %s
|
|
; RUN: llc -mtriple aarch64-windows -filetype asm -o - -global-isel -global-isel-abort=0 %s | FileCheck %s
|
|
|
|
define void @func() {
|
|
; CHECK-LABEL: func:
|
|
; CHECK: str x30, [sp, #-16]!
|
|
; CHECK-NEXT: .seh_save_reg_x x30, 16
|
|
; CHECK-NEXT: .seh_endprologue
|
|
; CHECK-NEXT: adrp x8, .refptr.weakfunc
|
|
; CHECK-NEXT: ldr x8, [x8, .refptr.weakfunc]
|
|
; CHECK-NEXT: cbz x8, .LBB0_2
|
|
; CHECK-NEXT: ; %bb.1:
|
|
; CHECK-NEXT: blr x8
|
|
; CHECK-NEXT: .LBB0_2:
|
|
; CHECK-NEXT: .seh_startepilogue
|
|
; CHECK-NEXT: ldr x30, [sp], #16
|
|
; CHECK-NEXT: .seh_save_reg_x x30, 16
|
|
; CHECK-NEXT: .seh_endepilogue
|
|
; CHECK-NEXT: ret
|
|
|
|
br i1 icmp ne (void ()* @weakfunc, void ()* null), label %1, label %2
|
|
|
|
1:
|
|
call void @weakfunc()
|
|
br label %2
|
|
|
|
2:
|
|
ret void
|
|
}
|
|
|
|
declare extern_weak void @weakfunc()
|