Mercurial > hg > CbC > CbC_llvm
comparison test/CodeGen/X86/hhvm-cc.ll @ 95:afa8332a0e37 LLVM3.8
LLVM 3.8
author | Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 13 Oct 2015 17:48:58 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
84:f3e34b893a5f | 95:afa8332a0e37 |
---|---|
1 ; RUN: llc < %s | FileCheck %s | |
2 | |
3 target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" | |
4 target triple = "x86_64-unknown-linux-gnu" | |
5 | |
6 declare hhvmcc i64 @bar(i64, i64, i64) nounwind | |
7 | |
8 ; Simply check we can modify %rbx and %rbp before returning via call to bar. | |
9 define hhvmcc i64 @foo(i64 %a, i64 %b, i64 %c) nounwind { | |
10 entry: | |
11 ; CHECK-LABEL: foo: | |
12 ; CHECK-DAG: movl $1, %ebx | |
13 ; CHECK-DAG: movl $3, %ebp | |
14 ; CHECK: jmp bar | |
15 %ret = musttail call hhvmcc i64 @bar(i64 1, i64 %b, i64 3) | |
16 ret i64 %ret | |
17 } | |
18 | |
19 ; Check that we can read and modify %rbx returned from PHP function. | |
20 define hhvmcc i64 @mod_return(i64 %a, i64 %b, i64 %c) nounwind { | |
21 entry: | |
22 ; CHECK-LABEL: mod_return: | |
23 ; CHECK-NEXT: {{^#.*}} | |
24 ; CHECK-NEXT: callq bar | |
25 ; CHECK-NEXT: incq %rbx | |
26 %tmp = call hhvmcc i64 @bar(i64 %a, i64 %b, i64 %c) | |
27 %retval = add i64 %tmp, 1 | |
28 ret i64 %retval | |
29 } | |
30 | |
31 %rettype = type { i64, i64, i64, i64, i64, i64, i64, | |
32 i64, i64, i64, i64, i64, i64, i64 | |
33 } | |
34 | |
35 ; Check that we can return up to 14 64-bit args in registers. | |
36 define hhvmcc %rettype @return_all(i64 %a, i64 %b, i64 %c) nounwind { | |
37 entry: | |
38 ; CHECK-LABEL: return_all: | |
39 ; CHECK-DAG: movl $1, %ebx | |
40 ; CHECK-DAG: movl $2, %ebp | |
41 ; CHECK-DAG: movl $3, %edi | |
42 ; CHECK-DAG: movl $4, %esi | |
43 ; CHECK-DAG: movl $5, %edx | |
44 ; CHECK-DAG: movl $6, %ecx | |
45 ; CHECK-DAG: movl $7, %r8 | |
46 ; CHECK-DAG: movl $8, %r9 | |
47 ; CHECK-DAG: movl $9, %eax | |
48 ; CHECK-DAG: movl $10, %r10 | |
49 ; CHECK-DAG: movl $11, %r11 | |
50 ; CHECK-DAG: movl $12, %r13 | |
51 ; CHECK-DAG: movl $13, %r14 | |
52 ; CHECK-DAG: movl $14, %r15 | |
53 ; CHECK: retq | |
54 %r1 = insertvalue %rettype zeroinitializer, i64 1, 0 | |
55 %r2 = insertvalue %rettype %r1, i64 2, 1 | |
56 %r3 = insertvalue %rettype %r2, i64 3, 2 | |
57 %r4 = insertvalue %rettype %r3, i64 4, 3 | |
58 %r5 = insertvalue %rettype %r4, i64 5, 4 | |
59 %r6 = insertvalue %rettype %r5, i64 6, 5 | |
60 %r7 = insertvalue %rettype %r6, i64 7, 6 | |
61 %r8 = insertvalue %rettype %r7, i64 8, 7 | |
62 %r9 = insertvalue %rettype %r8, i64 9, 8 | |
63 %r10 = insertvalue %rettype %r9, i64 10, 9 | |
64 %r11 = insertvalue %rettype %r10, i64 11, 10 | |
65 %r12 = insertvalue %rettype %r11, i64 12, 11 | |
66 %r13 = insertvalue %rettype %r12, i64 13, 12 | |
67 %r14 = insertvalue %rettype %r13, i64 14, 13 | |
68 ret %rettype %r14 | |
69 } | |
70 | |
71 declare hhvmcc void @return_all_tc(i64, i64, i64, i64, i64, i64, i64, i64, | |
72 i64, i64, i64, i64, i64, i64, i64) | |
73 | |
74 ; Check that we can return up to 14 64-bit args in registers via tail call. | |
75 define hhvmcc void @test_return_all_tc(i64 %a, i64 %b, i64 %c) nounwind { | |
76 entry: | |
77 ; CHECK-LABEL: test_return_all_tc: | |
78 ; CHECK-NEXT: {{^#.*}} | |
79 ; CHECK-DAG: movl $1, %ebx | |
80 ; CHECK-DAG: movl $3, %ebp | |
81 ; CHECK-DAG: movl $4, %r15 | |
82 ; CHECK-DAG: movl $5, %edi | |
83 ; CHECK-DAG: movl $6, %esi | |
84 ; CHECK-DAG: movl $7, %edx | |
85 ; CHECK-DAG: movl $8, %ecx | |
86 ; CHECK-DAG: movl $9, %r8 | |
87 ; CHECK-DAG: movl $10, %r9 | |
88 ; CHECK-DAG: movl $11, %eax | |
89 ; CHECK-DAG: movl $12, %r10 | |
90 ; CHECK-DAG: movl $13, %r11 | |
91 ; CHECK-DAG: movl $14, %r13 | |
92 ; CHECK-DAG: movl $15, %r14 | |
93 ; CHECK: jmp return_all_tc | |
94 tail call hhvmcc void @return_all_tc( | |
95 i64 1, i64 %b, i64 3, i64 4, i64 5, i64 6, i64 7, | |
96 i64 8, i64 9, i64 10, i64 11, i64 12, i64 13, i64 14, i64 15) | |
97 ret void | |
98 } | |
99 | |
100 declare hhvmcc {i64, i64} @php_short(i64, i64, i64, i64) | |
101 | |
102 define hhvmcc i64 @test_php_short(i64 %a, i64 %b, i64 %c) nounwind { | |
103 entry: | |
104 ; CHECK-LABEL: test_php_short: | |
105 ; CHECK-NEXT: {{^#.*}} | |
106 ; CHECK-NEXT: movl $42, %r15 | |
107 ; CHECK-NEXT: callq php_short | |
108 ; CHECK-NEXT: leaq (%rbp,%r12), %rbx | |
109 ; CHECK-NEXT: retq | |
110 %pair = call hhvmcc {i64, i64} @php_short(i64 %a, i64 %b, i64 %c, i64 42) | |
111 %fp = extractvalue {i64, i64} %pair, 1 | |
112 %rv = add i64 %fp, %b | |
113 ret i64 %rv | |
114 } | |
115 | |
116 declare hhvmcc %rettype @php_all(i64, i64, i64, i64, i64, i64, i64, | |
117 i64, i64, i64, i64, i64, i64, i64, i64) | |
118 | |
119 ; Check that we can pass 15 arguments in registers. | |
120 ; Also check that %r12 (2nd arg) is not spilled. | |
121 define hhvmcc i64 @test_php_all(i64 %a, i64 %b, i64 %c) nounwind { | |
122 entry: | |
123 ; CHECK-LABEL: test_php_all: | |
124 ; CHECK-NEXT: {{^#.*}} | |
125 ; CHECK-NOT: sub | |
126 ; CHECK-NOT: sub | |
127 ; CHECK-DAG: movl $1, %ebx | |
128 ; CHECK-DAG: movl $3, %ebp | |
129 ; CHECK-DAG: movl $4, %r15 | |
130 ; CHECK-DAG: movl $5, %edi | |
131 ; CHECK-DAG: movl $6, %esi | |
132 ; CHECK-DAG: movl $7, %edx | |
133 ; CHECK-DAG: movl $8, %ecx | |
134 ; CHECK-DAG: movl $9, %r8 | |
135 ; CHECK-DAG: movl $10, %r9 | |
136 ; CHECK-DAG: movl $11, %eax | |
137 ; CHECK-DAG: movl $12, %r10 | |
138 ; CHECK-DAG: movl $13, %r11 | |
139 ; CHECK-DAG: movl $14, %r13 | |
140 ; CHECK-DAG: movl $15, %r14 | |
141 ; CHECK: callq php_all | |
142 %pair = call hhvmcc %rettype @php_all( | |
143 i64 1, i64 %b, i64 3, i64 4, i64 5, i64 6, i64 7, | |
144 i64 8, i64 9, i64 10, i64 11, i64 12, i64 13, i64 14, i64 15) | |
145 %fp = extractvalue %rettype %pair, 1 | |
146 %rv = add i64 %fp, %b | |
147 ret i64 %rv | |
148 } | |
149 | |
150 declare hhvmcc void @svcreq(i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, | |
151 i64, i64) | |
152 | |
153 define hhvmcc void @test_svcreq(i64 %a, i64 %b, i64 %c) nounwind { | |
154 entry: | |
155 ; CHECK-LABEL: test_svcreq: | |
156 ; CHECK-DAG: movl $42, %r10 | |
157 ; CHECK-DAG: movl $1, %edi | |
158 ; CHECK-DAG: movl $2, %esi | |
159 ; CHECK-DAG: movl $3, %edx | |
160 ; CHECK-DAG: movl $4, %ecx | |
161 ; CHECK-DAG: movl $5, %r8 | |
162 ; CHECK-DAG: movl $6, %r9 | |
163 ; CHECK: jmp svcreq | |
164 tail call hhvmcc void @svcreq(i64 %a, i64 %b, i64 %c, i64 undef, i64 1, | |
165 i64 2, i64 3, i64 4, i64 5, i64 6, i64 undef, | |
166 i64 42) | |
167 ret void | |
168 } | |
169 | |
170 declare hhvm_ccc void @helper_short(i64, i64, i64, i64, i64, i64, i64) | |
171 | |
172 ; Pass all arguments in registers and check that we don't adjust stack | |
173 ; for the call. | |
174 define hhvmcc void @test_helper_short(i64 %a, i64 %b, i64 %c) nounwind { | |
175 entry: | |
176 ; CHECK-LABEL: test_helper_short: | |
177 ; CHECK-NOT: push | |
178 ; CHECK-NOT: sub | |
179 ; CHECK-DAG: movl $1, %edi | |
180 ; CHECK-DAG: movl $2, %esi | |
181 ; CHECK-DAG: movl $3, %edx | |
182 ; CHECK-DAG: movl $4, %ecx | |
183 ; CHECK-DAG: movl $5, %r8 | |
184 ; CHECK-DAG: movl $6, %r9 | |
185 ; CHECK: callq helper_short | |
186 call hhvm_ccc void @helper_short(i64 %c, i64 1, i64 2, i64 3, i64 4, | |
187 i64 5, i64 6) | |
188 ret void | |
189 } | |
190 | |
191 declare hhvm_ccc void @helper(i64, i64, i64, i64, i64, i64, i64, i64, i64, i64) | |
192 | |
193 define hhvmcc void @test_helper(i64 %a, i64 %b, i64 %c) nounwind { | |
194 entry: | |
195 ; CHECK-LABEL: test_helper: | |
196 ; CHECK-DAG: movl $1, %edi | |
197 ; CHECK-DAG: movl $2, %esi | |
198 ; CHECK-DAG: movl $3, %edx | |
199 ; CHECK-DAG: movl $4, %ecx | |
200 ; CHECK-DAG: movl $5, %r8 | |
201 ; CHECK-DAG: movl $6, %r9 | |
202 ; CHECK: callq helper | |
203 call hhvm_ccc void @helper(i64 %c, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, | |
204 i64 7, i64 8, i64 9) | |
205 ret void | |
206 } | |
207 | |
208 ; When we enter function with HHVM calling convention, the stack is aligned | |
209 ; at 16 bytes. This means we align objects on the stack differently and | |
210 ; adjust the stack differently for calls. | |
211 declare hhvm_ccc void @stack_helper(i64, i64, i64) | |
212 declare hhvm_ccc void @stack_helper2(<2 x double>, i64) | |
213 | |
214 define hhvmcc void @test_stack_helper(i64 %a, i64 %b, i64 %c) nounwind { | |
215 entry: | |
216 ; CHECK-LABEL: test_stack_helper: | |
217 ; CHECK-NOT: push | |
218 ; CHECK: subq $32, %rsp | |
219 ; CHECK: movaps 16(%rsp), %xmm0 | |
220 ; CHECK: callq stack_helper2 | |
221 %t1 = alloca <2 x double>, align 16 | |
222 %t2 = alloca i64, align 8 | |
223 %t3 = alloca i64, align 8 | |
224 %load3 = load i64, i64 *%t3 | |
225 call hhvm_ccc void @stack_helper(i64 %c, i64 %load3, i64 42) | |
226 %load = load <2 x double>, <2 x double> *%t1 | |
227 %load2 = load i64, i64 *%t2 | |
228 call hhvm_ccc void @stack_helper2(<2 x double> %load, i64 %load2) | |
229 ret void | |
230 } | |
231 | |
232 ; Check that we are not adjusting the stack before calling the helper. | |
233 define hhvmcc void @test_stack_helper2(i64 %a, i64 %b, i64 %c) nounwind { | |
234 entry: | |
235 ; CHECK-LABEL: test_stack_helper2: | |
236 ; CHECK-NOT: push | |
237 ; CHECK-NOT: subq | |
238 call hhvm_ccc void @stack_helper(i64 %c, i64 7, i64 42) | |
239 ret void | |
240 } | |
241 |