• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: llc < %s -mtriple=i386-linux-gnu  | FileCheck %s
2
3declare x86_regcallcc i32 @callee(i32 %a0, i32 %b0, i32 %c0, i32 %d0, i32 %e0);
4
5; In RegCall calling convention, ESI and EDI are callee saved registers.
6; One might think that the caller could assume that ESI value is the same before
7; and after calling the callee.
8; However, RegCall also says that a register that was used for
9; passing/returning argumnets, can be assumed to be modified by the callee.
10; In other words, it is no longer a callee saved register.
11; In this case we want to see that EDX/ECX values are saved and EDI/ESI are assumed
12; to be modified by the callee.
13; This is a hipe CC function that doesn't save any register for the caller.
14; So we can be sure that there is no other reason to save EDX/ECX.
15; The caller arguments are expected to be passed (in the following order)
16; in registers: ESI, EBP, EAX, EDX and ECX.
17define cc 11 i32 @caller(i32 %a0, i32 %b0, i32 %c0, i32 %d0, i32 %e0) nounwind {
18  %b1 = call x86_regcallcc i32 @callee(i32 %a0, i32 %b0, i32 %c0, i32 %d0, i32 %e0)
19  %b2 = add i32 %b1, %d0
20  %b3 = add i32 %b2, %e0
21  ret i32 %b3
22}
23; CHECK-LABEL:  caller
24; CHECK:        subl    $12, %esp
25; CHECK-NEXT:   movl    %ecx, 8(%esp)
26; CHECK-NEXT:   movl    %edx, %ebx
27; CHECK-NEXT:   movl    %eax, %edx
28; CHECK-NEXT:   movl    %esi, %eax
29; CHECK-NEXT:   movl    %ebp, %ecx
30; CHECK-NEXT:   movl    %ebx, %edi
31; CHECK-NEXT:   movl    8(%esp), %ebp
32; CHECK-NEXT:   movl    %ebp, %esi
33; CHECK-NEXT:   calll   callee
34; CHECK-NEXT:   leal    (%eax,%ebx), %esi
35; CHECK-NEXT:   addl    %ebp, %esi
36; CHECK-NEXT:   addl    $12, %esp
37; CHECK-NEXT:   retl
38
39!hipe.literals = !{ !0, !1, !2 }
40!0 = !{ !"P_NSP_LIMIT", i32 120 }
41!1 = !{ !"X86_LEAF_WORDS", i32 24 }
42!2 = !{ !"AMD64_LEAF_WORDS", i32 18 }
43
44; Make sure that the callee doesn't save parameters that were passed as arguments.
45; The caller arguments are expected to be passed (in the following order)
46; in registers: EAX, ECX, EDX, EDI and ESI.
47; The result will return in EAX, ECX and EDX.
48define x86_regcallcc {i32, i32, i32} @test_callee(i32 %a0, i32 %b0, i32 %c0, i32 %d0, i32 %e0) nounwind {
49  %b1 = mul i32 7, %e0
50  %b2 = udiv i32 5, %e0
51  %b3 = mul i32 7, %d0
52  %b4 = insertvalue {i32, i32, i32} undef, i32 %b1, 0
53  %b5 = insertvalue {i32, i32, i32} %b4, i32 %b2, 1
54  %b6 = insertvalue {i32, i32, i32} %b5, i32 %b3, 2
55  ret {i32, i32, i32} %b6
56}
57; CHECK-LABEL: test_callee
58; CHECK-NOT:   pushl %esi
59; CHECK-NOT:   pushl %edi
60; CHECK:       retl
61