2017-07-18 01:32:45 +08:00
|
|
|
; RUN: llc < %s -mtriple=i386-linux-gnu | FileCheck %s
|
2017-03-14 17:09:26 +08:00
|
|
|
|
|
|
|
declare x86_regcallcc i32 @callee(i32 %a0, i32 %b0, i32 %c0, i32 %d0, i32 %e0);
|
|
|
|
|
|
|
|
; In RegCall calling convention, ESI and EDI are callee saved registers.
|
|
|
|
; One might think that the caller could assume that ESI value is the same before
|
|
|
|
; and after calling the callee.
|
|
|
|
; However, RegCall also says that a register that was used for
|
|
|
|
; passing/returning argumnets, can be assumed to be modified by the callee.
|
|
|
|
; In other words, it is no longer a callee saved register.
|
|
|
|
; In this case we want to see that EDX/ECX values are saved and EDI/ESI are assumed
|
|
|
|
; to be modified by the callee.
|
|
|
|
; This is a hipe CC function that doesn't save any register for the caller.
|
|
|
|
; So we can be sure that there is no other reason to save EDX/ECX.
|
|
|
|
; The caller arguments are expected to be passed (in the following order)
|
|
|
|
; in registers: ESI, EBP, EAX, EDX and ECX.
|
|
|
|
define cc 11 i32 @caller(i32 %a0, i32 %b0, i32 %c0, i32 %d0, i32 %e0) nounwind {
|
|
|
|
%b1 = call x86_regcallcc i32 @callee(i32 %a0, i32 %b0, i32 %c0, i32 %d0, i32 %e0)
|
|
|
|
%b2 = add i32 %b1, %d0
|
|
|
|
%b3 = add i32 %b2, %e0
|
|
|
|
ret i32 %b3
|
|
|
|
}
|
|
|
|
; CHECK-LABEL: caller
|
|
|
|
; CHECK: subl $12, %esp
|
|
|
|
; CHECK-NEXT: movl %ecx, 8(%esp)
|
|
|
|
; CHECK-NEXT: movl %edx, %ebx
|
|
|
|
; CHECK-NEXT: movl %eax, %edx
|
|
|
|
; CHECK-NEXT: movl %esi, %eax
|
|
|
|
; CHECK-NEXT: movl %ebp, %ecx
|
|
|
|
; CHECK-NEXT: movl %ebx, %edi
|
|
|
|
; CHECK-NEXT: movl 8(%esp), %ebp
|
|
|
|
; CHECK-NEXT: movl %ebp, %esi
|
|
|
|
; CHECK-NEXT: calll callee
|
|
|
|
; CHECK-NEXT: leal (%eax,%ebx), %esi
|
|
|
|
; CHECK-NEXT: addl %ebp, %esi
|
|
|
|
; CHECK-NEXT: addl $12, %esp
|
|
|
|
; CHECK-NEXT: retl
|
|
|
|
|
|
|
|
!hipe.literals = !{ !0, !1, !2 }
|
|
|
|
!0 = !{ !"P_NSP_LIMIT", i32 120 }
|
|
|
|
!1 = !{ !"X86_LEAF_WORDS", i32 24 }
|
|
|
|
!2 = !{ !"AMD64_LEAF_WORDS", i32 18 }
|
|
|
|
|
|
|
|
; Make sure that the callee doesn't save parameters that were passed as arguments.
|
|
|
|
; The caller arguments are expected to be passed (in the following order)
|
|
|
|
; in registers: EAX, ECX, EDX, EDI and ESI.
|
|
|
|
; The result will return in EAX, ECX and EDX.
|
|
|
|
define x86_regcallcc {i32, i32, i32} @test_callee(i32 %a0, i32 %b0, i32 %c0, i32 %d0, i32 %e0) nounwind {
|
|
|
|
%b1 = mul i32 7, %e0
|
|
|
|
%b2 = udiv i32 5, %e0
|
|
|
|
%b3 = mul i32 7, %d0
|
|
|
|
%b4 = insertvalue {i32, i32, i32} undef, i32 %b1, 0
|
|
|
|
%b5 = insertvalue {i32, i32, i32} %b4, i32 %b2, 1
|
|
|
|
%b6 = insertvalue {i32, i32, i32} %b5, i32 %b3, 2
|
|
|
|
ret {i32, i32, i32} %b6
|
|
|
|
}
|
|
|
|
; CHECK-LABEL: test_callee
|
|
|
|
; CHECK-NOT: pushl %esi
|
|
|
|
; CHECK-NOT: pushl %edi
|
|
|
|
; CHECK: retl
|