mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
8382ecd17d
As the actual MSVC toolset doesn't use the GAS-style assembly that Clang/LLVM produces and consumes, there's no reference for what string to use for e.g. comments when building with a MSVC triple. This frees up the use of semicolon as separator string, just like was done for GNU targets in 23413195649d0cf6f3860ae8b5fb115b35032075. (Previously, both the separator and comment strings were set to the same, a semicolon.) Compiler-rt extensively uses separator chars in its assembly, and that assembly should be buildable with clang-cl for MSVC too. Differential Revision: https://reviews.llvm.org/D96259
198 lines
8.3 KiB
LLVM
198 lines
8.3 KiB
LLVM
; RUN: llc -o - %s -mtriple=aarch64-windows -verify-machineinstrs | FileCheck %s
|
|
; RUN: llc -o %t -filetype=obj %s -mtriple=aarch64-windows
|
|
; RUN: llvm-readobj --unwind %t | FileCheck %s -check-prefix=UNWIND
|
|
|
|
; We test the following
|
|
; 1) That the unwind help object is created and that its offset from the stack
|
|
; pointer on entry is patched into the table fed to __CxxFrameHandler3
|
|
; 2) That the stack update for the catch funclet only includes the callee saved
|
|
; registers
|
|
; 3) That the locals are accessed using the frame pointer in both the funclet
|
|
; and the parent function.
|
|
|
|
; The following checks that the unwind help object has -2 stored into it at
|
|
; fp + 16, which is on-entry sp - 16.
|
|
; We check this offset in the table later on.
|
|
|
|
; CHECK-LABEL: "?func@@YAHXZ":
|
|
; CHECK: stp x19, x20, [sp, #-64]!
|
|
; CHECK: str x21, [sp, #16]
|
|
; CHECK: str x28, [sp, #24]
|
|
; CHECK: stp x29, x30, [sp, #32]
|
|
; CHECK: add x29, sp, #32
|
|
; CHECK: sub sp, sp, #624
|
|
; CHECK: mov x19, sp
|
|
; CHECK: mov x0, #-2
|
|
; CHECK: stur x0, [x29, #16]
|
|
|
|
; Now check that x is stored at fp - 20. We check that this is the same
|
|
; location accessed from the funclet to retrieve x.
|
|
; CHECK: mov w8, #1
|
|
; CHECK: stur w8, [x29, [[X_OFFSET:#-[1-9][0-9]+]]
|
|
|
|
; Check the offset off the frame pointer at which B is located.
|
|
; Check the same offset is used to pass the address of B to init2 in the
|
|
; funclet.
|
|
; CHECK: sub x0, x29, [[B_OFFSET:#[1-9][0-9]+]]
|
|
; CHECK: bl "?init@@YAXPEAH@Z"
|
|
|
|
; This is the label for the throw that is encoded in the ip2state.
|
|
; We are inside the try block, where we make a call to func2
|
|
; CHECK-LABEL: .Ltmp0:
|
|
; CHECK: bl "?func2@@YAHXZ
|
|
|
|
; CHECK: [[CATCHRETDEST:.LBB0_[0-9]+]]: // %catchret.dest
|
|
|
|
; Check the catch funclet.
|
|
; CHECK-LABEL: "?catch$2@?0??func@@YAHXZ@4HA":
|
|
|
|
; Check that the stack space is allocated only for the callee saved registers.
|
|
; CHECK: stp x19, x20, [sp, #-48]!
|
|
; CHECK: str x21, [sp, #16]
|
|
; CHECK: str x28, [sp, #24]
|
|
; CHECK: stp x29, x30, [sp, #32]
|
|
; CHECK: add x20, x19, #12
|
|
|
|
; Check that there are no further stack updates.
|
|
; CHECK-NOT: sub sp, sp
|
|
|
|
; Check that the stack address passed to init2 is off the frame pointer, and
|
|
; that it matches the address of B in the parent function.
|
|
; CHECK: sub x0, x29, [[B_OFFSET]]
|
|
; CHECK: bl "?init2@@YAXPEAH@Z"
|
|
|
|
; Check that are storing x back to the same location off the frame pointer as in
|
|
; the parent function.
|
|
; CHECK: stur w8, [x29, [[X_OFFSET]]]
|
|
|
|
; Check that the funclet branches back to the catchret destination
|
|
; CHECK: adrp x0, .LBB0_3
|
|
; CHECK-NEXT: add x0, x0, [[CATCHRETDEST]]
|
|
|
|
|
|
; Now check that the offset of the unwind help object from the stack pointer on
|
|
; entry to func is encoded in cppxdata that is passed to __CxxFrameHandler3. As
|
|
; computed above, this comes to -16.
|
|
; CHECK-LABEL: "$cppxdata$?func@@YAHXZ":
|
|
; CHECK-NEXT: .word 429065506 // MagicNumber
|
|
; CHECK-NEXT: .word 2 // MaxState
|
|
; CHECK-NEXT: .word ("$stateUnwindMap$?func@@YAHXZ")@IMGREL // UnwindMap
|
|
; CHECK-NEXT: .word 1 // NumTryBlocks
|
|
; CHECK-NEXT: .word ("$tryMap$?func@@YAHXZ")@IMGREL // TryBlockMap
|
|
; CHECK-NEXT: .word 4 // IPMapEntries
|
|
; CHECK-NEXT: .word ("$ip2state$?func@@YAHXZ")@IMGREL // IPToStateXData
|
|
; CHECK-NEXT: .word -16 // UnwindHelp
|
|
|
|
; UNWIND: Function: ?func@@YAHXZ (0x0)
|
|
; UNWIND: Prologue [
|
|
; UNWIND-NEXT: ; nop
|
|
; UNWIND-NEXT: ; sub sp, #624
|
|
; UNWIND-NEXT: ; add fp, sp, #32
|
|
; UNWIND-NEXT: ; stp x29, x30, [sp, #32]
|
|
; UNWIND-NEXT: ; str x28, [sp, #24]
|
|
; UNWIND-NEXT: ; str x21, [sp, #16]
|
|
; UNWIND-NEXT: ; stp x19, x20, [sp, #-64]!
|
|
; UNWIND-NEXT: ; end
|
|
; UNWIND: Function: ?catch$2@?0??func@@YAHXZ@4HA
|
|
; UNWIND: Prologue [
|
|
; UNWIND-NEXT: ; stp x29, x30, [sp, #32]
|
|
; UNWIND-NEXT: ; str x28, [sp, #24]
|
|
; UNWIND-NEXT: ; str x21, [sp, #16]
|
|
; UNWIND-NEXT: ; stp x19, x20, [sp, #-48]!
|
|
; UNWIND-NEXT: ; end
|
|
|
|
target datalayout = "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128"
|
|
target triple = "aarch64-unknown-windows-msvc19.11.0"
|
|
|
|
%rtti.TypeDescriptor2 = type { i8**, i8*, [3 x i8] }
|
|
%eh.CatchableType = type { i32, i32, i32, i32, i32, i32, i32 }
|
|
%eh.CatchableTypeArray.1 = type { i32, [1 x i32] }
|
|
%eh.ThrowInfo = type { i32, i32, i32, i32 }
|
|
|
|
$"??_R0H@8" = comdat any
|
|
|
|
$"_CT??_R0H@84" = comdat any
|
|
|
|
$_CTA1H = comdat any
|
|
|
|
$_TI1H = comdat any
|
|
|
|
@"??_7type_info@@6B@" = external constant i8*
|
|
@"??_R0H@8" = linkonce_odr global %rtti.TypeDescriptor2 { i8** @"??_7type_info@@6B@", i8* null, [3 x i8] c".H\00" }, comdat
|
|
@__ImageBase = external dso_local constant i8
|
|
@"_CT??_R0H@84" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor2* @"??_R0H@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 -1, i32 0, i32 4, i32 0 }, section ".xdata", comdat
|
|
@_CTA1H = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.1 { i32 1, [1 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%eh.CatchableType* @"_CT??_R0H@84" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32)] }, section ".xdata", comdat
|
|
@_TI1H = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%eh.CatchableTypeArray.1* @_CTA1H to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, section ".xdata", comdat
|
|
|
|
; Function Attrs: noinline optnone
|
|
define dso_local i32 @"?func@@YAHXZ"() #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
|
|
entry:
|
|
%B = alloca [50 x i32], align 4
|
|
%x = alloca i32, align 4
|
|
%tmp = alloca i32, align 4
|
|
%i = alloca i32, align 4
|
|
%C = alloca [100 x i32], align 4
|
|
store i32 1, i32* %x, align 4
|
|
%arraydecay = getelementptr inbounds [50 x i32], [50 x i32]* %B, i32 0, i32 0
|
|
call void @"?init@@YAXPEAH@Z"(i32* %arraydecay)
|
|
%call = invoke i32 @"?func2@@YAHXZ"()
|
|
to label %invoke.cont unwind label %catch.dispatch
|
|
|
|
invoke.cont: ; preds = %entry
|
|
store i32 %call, i32* %tmp, align 4
|
|
%0 = bitcast i32* %tmp to i8*
|
|
invoke void @_CxxThrowException(i8* %0, %eh.ThrowInfo* @_TI1H) #2
|
|
to label %unreachable unwind label %catch.dispatch
|
|
|
|
catch.dispatch: ; preds = %invoke.cont, %entry
|
|
%1 = catchswitch within none [label %catch] unwind to caller
|
|
|
|
catch: ; preds = %catch.dispatch
|
|
%2 = catchpad within %1 [%rtti.TypeDescriptor2* @"??_R0H@8", i32 0, i32* %i]
|
|
%arraydecay1 = getelementptr inbounds [100 x i32], [100 x i32]* %C, i32 0, i32 0
|
|
call void @"?init@@YAXPEAH@Z"(i32* %arraydecay1) [ "funclet"(token %2) ]
|
|
%arraydecay2 = getelementptr inbounds [50 x i32], [50 x i32]* %B, i32 0, i32 0
|
|
call void @"?init2@@YAXPEAH@Z"(i32* %arraydecay2) [ "funclet"(token %2) ]
|
|
%3 = load i32, i32* %i, align 4
|
|
%idxprom = sext i32 %3 to i64
|
|
%arrayidx = getelementptr inbounds [50 x i32], [50 x i32]* %B, i64 0, i64 %idxprom
|
|
%4 = load i32, i32* %arrayidx, align 4
|
|
%5 = load i32, i32* %i, align 4
|
|
%idxprom3 = sext i32 %5 to i64
|
|
%arrayidx4 = getelementptr inbounds [100 x i32], [100 x i32]* %C, i64 0, i64 %idxprom3
|
|
%6 = load i32, i32* %arrayidx4, align 4
|
|
%add = add nsw i32 %4, %6
|
|
%7 = load i32, i32* %i, align 4
|
|
%8 = load i32, i32* %i, align 4
|
|
%mul = mul nsw i32 %7, %8
|
|
%add5 = add nsw i32 %add, %mul
|
|
store i32 %add5, i32* %x, align 4
|
|
catchret from %2 to label %catchret.dest
|
|
|
|
catchret.dest: ; preds = %catch
|
|
br label %try.cont
|
|
|
|
try.cont: ; preds = %catchret.dest
|
|
%arrayidx6 = getelementptr inbounds [50 x i32], [50 x i32]* %B, i64 0, i64 2
|
|
%9 = load i32, i32* %arrayidx6, align 4
|
|
%10 = load i32, i32* %x, align 4
|
|
%add7 = add nsw i32 %9, %10
|
|
ret i32 %add7
|
|
|
|
unreachable: ; preds = %invoke.cont
|
|
unreachable
|
|
}
|
|
|
|
declare dso_local void @"?init@@YAXPEAH@Z"(i32*)
|
|
|
|
declare dso_local i32 @"?func2@@YAHXZ"()
|
|
|
|
declare dso_local i32 @__CxxFrameHandler3(...)
|
|
|
|
declare dllimport void @_CxxThrowException(i8*, %eh.ThrowInfo*)
|
|
|
|
declare dso_local void @"?init2@@YAXPEAH@Z"(i32*)
|
|
|
|
attributes #0 = { noinline optnone }
|
|
attributes #2 = { noreturn }
|