1; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu < %s | FileCheck %s
2
3; Paramater Save Area is not needed if number of parameter does not exceed
4; number of registers
5; ------------------------------------------------------------------------------
6
7; Max number of GPR is 8
8define linkonce_odr void
9    @WithoutParamArea(i8* %a, i32 signext %b) align 2 {
10entry:
11  call fastcc void @fastccFunc(i32 signext 1)
12  ret void
13
14; CHECK-LABEL: WithoutParamArea
15; CHECK: stdu 1, -32(1)
16; CHECK: blr
17}
18declare fastcc void @fastccFunc(i32 signext %level) unnamed_addr
19
20; No need for Parameter Save Area if only 8 GPRs is needed.
21define linkonce_odr void @WithoutParamArea2(i8* %a, i32 signext %b) align 2 {
22entry:
23  call fastcc void @eightArgs(i32 signext 1, i32 signext 2, i32 signext 3,
24                              i32 signext 4, i32 signext 5, i32 signext 6,
25                              i32 signext 7, i32 signext 8)
26  ret void
27
28; CHECK-LABEL: WithoutParamArea2
29; CHECK: stdu 1, -32(1)
30; CHECK: blr
31}
32
33declare fastcc void
34    @eightArgs(i32 signext %level, i32 signext %level2, i32 signext %level3,
35               i32 signext %level4, i32 signext %level5, i32 signext %level6,
36               i32 signext %level7, i32 signext %level8) unnamed_addr
37
38; No need for Parameter Save Area for calls that utiliizes 8 GPR and 2 FPR.
39define linkonce_odr void @WithoutParamArea3(i8* %a, i32 signext %b) align 2 {
40entry:
41  call fastcc void
42      @mixedArgs(i32 signext 1, float 1.0, i32 signext 2, float 2.0,
43                 i32 signext 3, i32 signext 4, i32 signext 5, i32 signext 6,
44                 i32 signext 7, i32 signext 8) ret void
45  ret void
46
47; CHECK-LABEL: WithoutParamArea3
48; CHECK: stdu 1, -32(1)
49; CHECK: blr
50}
51
52declare fastcc void
53    @mixedArgs(i32 signext %level, float %levelf1, i32 signext %level2,
54               float %levelf2, i32 signext %level3, i32 signext %level4,
55               i32 signext %level5, i32 signext %level6, i32 signext %level7,
56               i32 signext %level8) unnamed_addr
57
58; Pass by value usage requiring less GPR then available
59%"myClass::Mem" = type { i8, i8, i16, i32, i32, i32, i64 }
60
61define internal fastcc void @CallPassByValue(%"myClass::Mem"* %E) align 2 {
62entry:
63  call fastcc void @PassByValue(%"myClass::Mem"* byval(%"myClass::Mem") nonnull align 8 undef);
64  ret void
65
66; CHECK-LABEL: PassByValue
67; CHECK: stdu 1, -32(1)
68; CHECK: blr
69}
70
71declare dso_local fastcc void
72    @PassByValue(%"myClass::Mem"* byval(%"myClass::Mem") nocapture readonly align 8) align 2
73
74; Verify Paramater Save Area is allocated if parameter exceed the number that
75; can be passed via registers
76; ------------------------------------------------------------------------------
77
78; Max number of GPR is 8
79define linkonce_odr void @WithParamArea(i8 * %a, i32 signext %b) align 2 {
80entry:
81  call fastcc void @nineArgs(i32 signext 1, i32 signext 2, i32 signext 3,
82                           i32 signext 4, i32 signext 5, i32 signext 6,
83                           i32 signext 7, i32 signext 8, i32 signext 9)
84  ret void
85
86; CHECK-LABEL: WithParamArea
87; CHECK: stdu 1, -96(1)
88; CHECK: blr
89}
90
91declare fastcc void @nineArgs(i32 signext %level, i32 signext %level2,
92  i32 signext %level3, i32 signext %level4, i32 signext %level5,
93  i32 signext %level6, i32 signext %level7, i32 signext %level8,
94  i32 signext %level9) unnamed_addr
95
96; Max number of FPR for parameter passing is 13
97define linkonce_odr void @WithParamArea2(i8* %a, i32 signext %b) align 2 {
98entry:
99  call fastcc void @funcW14FloatArgs(float 1.0, float 2.0, float 3.0,
100    float 4.0, float 5.0, float 6.0, float 7.0, float 8.0, float 1.0,
101    float 2.0, float 3.0, float 4.0, float 5.0, float 14.0)
102  ret void
103
104; CHECK-LABEL: WithParamArea2
105; CHECK: stdu 1, -96(1)
106; CHECK: blr
107}
108
109declare fastcc void
110    @funcW14FloatArgs(float %level, float %level2, float %level3,
111                      float %level4, float %level5, float %level6,
112                      float %level7, float %level8, float %level9,
113                      float %level10, float %level11, float %level12,
114                      float %level13, float %level14);
115
116
117; Pass by value usage requires more GPR then available
118%"myClass::MemA" = type { i8, i8, i16, i32, i32, i32, i64 }
119%"myClass::MemB" = type { i32*, i32, i32, %"myClass::MemB"** }
120%"myClass::MemC" = type { %"myClass::MemD"*, %"myClass::MemC"*, i64 }
121%"myClass::MemD" = type { %"myClass::MemB"*, %"myClass::MemC"*, i8, i8, i16,
122              i32 }
123%"myStruct::MemF" = type { i32, %"myClass::MemA"*, %"myClass::MemA"*, i64, i64 }
124%"myClass::MemK" = type { i32, %"myClass::MemD"*, %"myClass::MemD"*, i64, i32,
125                          i64, i8, i32, %"myStruct::MemF",
126              i8, %"myClass::MemA"* }
127
128define internal fastcc void @AggMemExprEmitter(%"myClass::MemK"* %E) align 2 {
129entry:
130  call fastcc void @MemExprEmitterInitialization(%"myClass::MemK"*
131                                               byval(%"myClass::MemK") nonnull align 8 undef);
132  ret void
133
134; CHECK-LABEL: AggMemExprEmitter
135; CHECK: stdu 1, -144(1)
136; CHECK: blr
137}
138
139declare dso_local fastcc void
140    @MemExprEmitterInitialization(%"myClass::MemK"*
141                                  byval(%"myClass::MemK") nocapture readonly align 8) align 2
142