
Windows x64 Unwind V2 adds epilog information to unwind data: specifically, the length of the epilog and the offset of each epilog. The first step to do this is to add markers to the beginning and end of each epilog when generating Windows x64 code. I've modelled this after how LLVM was marking ARM and AArch64 epilogs in Windows (and unified the code between the three).
130 lines
4.4 KiB
LLVM
130 lines
4.4 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
; When we accept small parameters on Windows, make sure we do not assume they
|
|
; are zero or sign extended in memory or in registers.
|
|
|
|
; RUN: llc < %s -mtriple=x86_64-windows-msvc | FileCheck %s --check-prefix=WIN64
|
|
; RUN: llc < %s -mtriple=x86_64-windows-gnu | FileCheck %s --check-prefix=WIN64
|
|
; RUN: llc < %s -mtriple=i686-windows-msvc | FileCheck %s --check-prefix=WIN32-MSVC
|
|
; RUN: llc < %s -mtriple=i686-windows-gnu | FileCheck %s --check-prefix=WIN32-GNU
|
|
|
|
define void @call() {
|
|
; WIN64-LABEL: call:
|
|
; WIN64: # %bb.0: # %entry
|
|
; WIN64-NEXT: subq $56, %rsp
|
|
; WIN64-NEXT: .seh_stackalloc 56
|
|
; WIN64-NEXT: .seh_endprologue
|
|
; WIN64-NEXT: movw $6, {{[0-9]+}}(%rsp)
|
|
; WIN64-NEXT: movb $5, {{[0-9]+}}(%rsp)
|
|
; WIN64-NEXT: movb $1, %cl
|
|
; WIN64-NEXT: movw $2, %dx
|
|
; WIN64-NEXT: movb $3, %r8b
|
|
; WIN64-NEXT: movw $4, %r9w
|
|
; WIN64-NEXT: callq manyargs
|
|
; WIN64-NEXT: nop
|
|
; WIN64-NEXT: .seh_startepilogue
|
|
; WIN64-NEXT: addq $56, %rsp
|
|
; WIN64-NEXT: .seh_endepilogue
|
|
; WIN64-NEXT: retq
|
|
; WIN64-NEXT: .seh_endproc
|
|
;
|
|
; WIN32-MSVC-LABEL: call:
|
|
; WIN32-MSVC: # %bb.0: # %entry
|
|
; WIN32-MSVC-NEXT: pushl $6
|
|
; WIN32-MSVC-NEXT: pushl $5
|
|
; WIN32-MSVC-NEXT: pushl $4
|
|
; WIN32-MSVC-NEXT: pushl $3
|
|
; WIN32-MSVC-NEXT: pushl $2
|
|
; WIN32-MSVC-NEXT: pushl $1
|
|
; WIN32-MSVC-NEXT: calll _manyargs
|
|
; WIN32-MSVC-NEXT: addl $24, %esp
|
|
; WIN32-MSVC-NEXT: retl
|
|
;
|
|
; WIN32-GNU-LABEL: call:
|
|
; WIN32-GNU: # %bb.0: # %entry
|
|
; WIN32-GNU-NEXT: pushl $6
|
|
; WIN32-GNU-NEXT: .cfi_adjust_cfa_offset 4
|
|
; WIN32-GNU-NEXT: pushl $5
|
|
; WIN32-GNU-NEXT: .cfi_adjust_cfa_offset 4
|
|
; WIN32-GNU-NEXT: pushl $4
|
|
; WIN32-GNU-NEXT: .cfi_adjust_cfa_offset 4
|
|
; WIN32-GNU-NEXT: pushl $3
|
|
; WIN32-GNU-NEXT: .cfi_adjust_cfa_offset 4
|
|
; WIN32-GNU-NEXT: pushl $2
|
|
; WIN32-GNU-NEXT: .cfi_adjust_cfa_offset 4
|
|
; WIN32-GNU-NEXT: pushl $1
|
|
; WIN32-GNU-NEXT: .cfi_adjust_cfa_offset 4
|
|
; WIN32-GNU-NEXT: calll _manyargs
|
|
; WIN32-GNU-NEXT: addl $24, %esp
|
|
; WIN32-GNU-NEXT: .cfi_adjust_cfa_offset -24
|
|
; WIN32-GNU-NEXT: retl
|
|
entry:
|
|
%rv = call i32 @manyargs(i8 1, i16 2, i8 3, i16 4, i8 5, i16 6)
|
|
ret void
|
|
}
|
|
|
|
define i32 @manyargs(i8 %a, i16 %b, i8 %c, i16 %d, i8 %e, i16 %f) {
|
|
; WIN64-LABEL: manyargs:
|
|
; WIN64: # %bb.0: # %entry
|
|
; WIN64-NEXT: movzwl {{[0-9]+}}(%rsp), %r10d
|
|
; WIN64-NEXT: movzbl {{[0-9]+}}(%rsp), %r11d
|
|
; WIN64-NEXT: movsbl %cl, %eax
|
|
; WIN64-NEXT: movswl %dx, %ecx
|
|
; WIN64-NEXT: addl %eax, %ecx
|
|
; WIN64-NEXT: movzbl %r8b, %edx
|
|
; WIN64-NEXT: movzwl %r9w, %eax
|
|
; WIN64-NEXT: addl %edx, %eax
|
|
; WIN64-NEXT: addl %ecx, %eax
|
|
; WIN64-NEXT: addl %r11d, %eax
|
|
; WIN64-NEXT: addl %r10d, %eax
|
|
; WIN64-NEXT: retq
|
|
;
|
|
; WIN32-MSVC-LABEL: manyargs:
|
|
; WIN32-MSVC: # %bb.0: # %entry
|
|
; WIN32-MSVC-NEXT: pushl %esi
|
|
; WIN32-MSVC-NEXT: movzwl {{[0-9]+}}(%esp), %eax
|
|
; WIN32-MSVC-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
|
|
; WIN32-MSVC-NEXT: addl %eax, %ecx
|
|
; WIN32-MSVC-NEXT: movzwl {{[0-9]+}}(%esp), %eax
|
|
; WIN32-MSVC-NEXT: movzbl {{[0-9]+}}(%esp), %edx
|
|
; WIN32-MSVC-NEXT: addl %eax, %edx
|
|
; WIN32-MSVC-NEXT: movswl {{[0-9]+}}(%esp), %esi
|
|
; WIN32-MSVC-NEXT: movsbl {{[0-9]+}}(%esp), %eax
|
|
; WIN32-MSVC-NEXT: addl %esi, %eax
|
|
; WIN32-MSVC-NEXT: addl %edx, %eax
|
|
; WIN32-MSVC-NEXT: addl %ecx, %eax
|
|
; WIN32-MSVC-NEXT: popl %esi
|
|
; WIN32-MSVC-NEXT: retl
|
|
;
|
|
; WIN32-GNU-LABEL: manyargs:
|
|
; WIN32-GNU: # %bb.0: # %entry
|
|
; WIN32-GNU-NEXT: pushl %esi
|
|
; WIN32-GNU-NEXT: .cfi_def_cfa_offset 8
|
|
; WIN32-GNU-NEXT: .cfi_offset %esi, -8
|
|
; WIN32-GNU-NEXT: movzwl {{[0-9]+}}(%esp), %eax
|
|
; WIN32-GNU-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
|
|
; WIN32-GNU-NEXT: addl %eax, %ecx
|
|
; WIN32-GNU-NEXT: movzwl {{[0-9]+}}(%esp), %eax
|
|
; WIN32-GNU-NEXT: movzbl {{[0-9]+}}(%esp), %edx
|
|
; WIN32-GNU-NEXT: addl %eax, %edx
|
|
; WIN32-GNU-NEXT: movswl {{[0-9]+}}(%esp), %esi
|
|
; WIN32-GNU-NEXT: movsbl {{[0-9]+}}(%esp), %eax
|
|
; WIN32-GNU-NEXT: addl %esi, %eax
|
|
; WIN32-GNU-NEXT: addl %edx, %eax
|
|
; WIN32-GNU-NEXT: addl %ecx, %eax
|
|
; WIN32-GNU-NEXT: popl %esi
|
|
; WIN32-GNU-NEXT: retl
|
|
entry:
|
|
%aa = sext i8 %a to i32
|
|
%bb = sext i16 %b to i32
|
|
%cc = zext i8 %c to i32
|
|
%dd = zext i16 %d to i32
|
|
%ee = zext i8 %e to i32
|
|
%ff = zext i16 %f to i32
|
|
%t0 = add i32 %aa, %bb
|
|
%t1 = add i32 %t0, %cc
|
|
%t2 = add i32 %t1, %dd
|
|
%t3 = add i32 %t2, %ee
|
|
%t4 = add i32 %t3, %ff
|
|
ret i32 %t4
|
|
}
|