Fix typo.
[oota-llvm.git] / test / CodeGen / PowerPC / ppc64-i128-abi.ll
1 ; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr8 < %s | FileCheck %s -check-prefix=CHECK-LE
2 ; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr8 < %s | FileCheck %s -check-prefix=CHECK-BE
3 ; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr8 -mattr=-vsx < %s | FileCheck %s -check-prefix=CHECK-NOVSX
4 ; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr8 -mattr=-vsx < %s | FileCheck %s -check-prefix=CHECK-NOVSX
5 ; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr8 -mattr=-vsx < %s | FileCheck %s -check-prefix=CHECK-BE-NOVSX
6 ; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr8 -mattr=-vsx < %s | FileCheck %s -check-prefix=CHECK-LE-NOVSX
7
8 @x = common global <1 x i128> zeroinitializer, align 16
9 @y = common global <1 x i128> zeroinitializer, align 16
10 @a = common global i128 zeroinitializer, align 16
11 @b = common global i128 zeroinitializer, align 16
12
13 ; VSX:
14 ;   %a is passed in register 34
15 ;   The value of 1 is stored in the TOC.
16 ;   On LE, ensure the value of 1 is swapped before being used (using xxswapd).
17 ; VMX (no VSX): 
18 ;   %a is passed in register 2
19 ;   The value of 1 is stored in the TOC.
20 ;   No swaps are necessary when using P8 Vector instructions on LE
21 define <1 x i128> @v1i128_increment_by_one(<1 x i128> %a) nounwind {
22        %tmp = add <1 x i128> %a, <i128 1>
23        ret <1 x i128> %tmp  
24
25 ; FIXME: Seems a 128-bit literal is materialized by loading from the TOC. There
26 ;        should be a better way of doing this.
27
28 ; CHECK-LE-LABEL: @v1i128_increment_by_one
29 ; CHECK-LE: lxvd2x [[VAL:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
30 ; CHECK-LE: xxswapd 35, [[VAL]]
31 ; CHECK-LE: vadduqm 2, 2, 3
32 ; CHECK-LE: blr
33
34 ; CHECK-BE-LABEL: @v1i128_increment_by_one
35 ; CHECK-BE: lxvd2x 35, {{[0-9]+}}, {{[0-9]+}}
36 ; CHECK-BE-NOT: xxswapd 
37 ; CHECK-BE: vadduqm 2, 2, 3 
38 ; CHECK-BE-NOT: xxswapd 34, {{[0-9]+}}
39 ; CHECK-BE: blr
40
41 ; CHECK-NOVSX-LABEL: @v1i128_increment_by_one
42 ; CHECK-NOVSX-NOT: xxswapd {{[0-9]+}}, {{[0-9]+}}
43 ; CHECK-NOVSX-NOT: stxvd2x {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
44 ; CHECK-NOVSX: lvx [[VAL:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
45 ; CHECK-NOVSX-NOT: lxvd2x {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
46 ; CHECK-NOVSX-NOT: xxswapd {{[0-9]+}}, {{[0-9]+}}
47 ; CHECK-NOVSX: vadduqm 2, 2, [[VAL]]
48 ; CHECK-NOVSX: blr
49 }
50
51 ; VSX:
52 ;   %a is passed in register 34
53 ;   %b is passed in register 35
54 ;   No swaps are necessary when using P8 Vector instructions on LE
55 ; VMX (no VSX):
56 ;   %a is passewd in register 2
57 ;   %b is passed in register 3
58 ;   On LE, do not need to swap contents of 2 and 3 because the lvx/stvx 
59 ;   instructions no not swap elements
60 define <1 x i128> @v1i128_increment_by_val(<1 x i128> %a, <1 x i128> %b) nounwind {
61        %tmp = add <1 x i128> %a, %b
62        ret <1 x i128> %tmp
63
64 ; CHECK-LE-LABEL: @v1i128_increment_by_val
65 ; CHECK-LE-NOT: xxswapd
66 ; CHECK-LE: adduqm 2, 2, 3
67 ; CHECK-LE: blr
68
69 ; CHECK-BE-LABEL: @v1i128_increment_by_val
70 ; CHECK-BE-NOT: xxswapd {{[0-9]+}}, 34
71 ; CHECK-BE-NOT: xxswapd {{[0-9]+}}, 35
72 ; CHECK-BE-NOT: xxswapd 34, [[RESULT]]
73 ; CHECK-BE: adduqm 2, 2, 3
74 ; CHECK-BE: blr
75
76 ; CHECK-NOVSX-LABEL: @v1i128_increment_by_val
77 ; CHECK-NOVSX-NOT: xxswapd 34, [[RESULT]]
78 ; CHECK-NOVSX: adduqm 2, 2, 3
79 ; CHECK-NOVSX: blr
80 }
81
82 ; Little Endian (VSX and VMX):
83 ;   Lower 64-bits of %a are passed in register 3
84 ;   Upper 64-bits of %a are passed in register 4
85 ;   Increment lower 64-bits using addic (immediate value of 1)
86 ;   Increment upper 64-bits using add zero extended
87 ;   Results are placed in registers 3 and 4
88 ; Big Endian (VSX and VMX)
89 ;   Lower 64-bits of %a are passed in register 4
90 ;   Upper 64-bits of %a are passed in register 3
91 ;   Increment lower 64-bits using addic (immediate value of 1)
92 ;   Increment upper 64-bits using add zero extended
93 ;   Results are placed in registers 3 and 4
94 define i128 @i128_increment_by_one(i128 %a) nounwind {
95        %tmp =  add i128 %a,  1
96        ret i128 %tmp
97 ; CHECK-LE-LABEL: @i128_increment_by_one
98 ; CHECK-LE: addic 3, 3, 1
99 ; CHECK-LE-NEXT: addze 4, 4
100 ; CHECK-LE: blr
101
102 ; CHECK-BE-LABEL: @i128_increment_by_one
103 ; CHECK-BE: addic 4, 4, 1
104 ; CHECK-BE-NEXT: addze 3, 3
105 ; CHECK-BE: blr
106
107 ; CHECK-LE-NOVSX-LABEL: @i128_increment_by_one
108 ; CHECK-LE-NOVSX: addic 3, 3, 1
109 ; CHECK-LE-NOVSX-NEXT: addze 4, 4
110 ; CHECK-LE-NOVSX: blr
111
112 ; CHECK-BE-NOVSX-LABEL: @i128_increment_by_one
113 ; CHECK-BE-NOVSX: addic 4, 4, 1
114 ; CHECK-BE-NOVSX-NEXT: addze 3, 3
115 ; CHECK-BE-NOVSX: blr
116 }
117
118 ; Little Endian (VSX and VMX):
119 ;   Lower 64-bits of %a are passed in register 3
120 ;   Upper 64-bits of %a are passed in register 4
121 ;   Lower 64-bits of %b are passed in register 5
122 ;   Upper 64-bits of %b are passed in register 6
123 ;   Add the lower 64-bits using addc on registers 3 and 5
124 ;   Add the upper 64-bits using adde on registers 4 and 6
125 ;   Registers 3 and 4 should hold the result
126 ; Big Endian (VSX and VMX):
127 ;   Upper 64-bits of %a are passed in register 3
128 ;   Lower 64-bits of %a are passed in register 4
129 ;   Upper 64-bits of %b are passed in register 5
130 ;   Lower 64-bits of %b are passed in register 6
131 ;   Add the lower 64-bits using addc on registers 4 and 6
132 ;   Add the upper 64-bits using adde on registers 3 and 5
133 ;   Registers 3 and 4 should hold the result
134 define i128 @i128_increment_by_val(i128 %a, i128 %b) nounwind {
135        %tmp =  add i128 %a, %b
136        ret i128 %tmp
137 ; CHECK-LE-LABEL: @i128_increment_by_val
138 ; CHECK-LE: addc 3, 3, 5
139 ; CHECK-LE-NEXT: adde 4, 4, 6
140 ; CHECK-LE: blr
141
142 ; CHECK-BE-LABEL: @i128_increment_by_val
143 ; CHECK-BE: addc 4, 4, 6
144 ; CHECK-BE-NEXT: adde 3, 3, 5
145 ; CHECK-BE: blr
146
147 ; CHECK-LE-NOVSX-LABEL: @i128_increment_by_val
148 ; CHECK-LE-NOVSX: addc 3, 3, 5
149 ; CHECK-LE-NOVSX-NEXT: adde 4, 4, 6
150 ; CHECK-LE-NOVSX: blr
151
152 ; CHECK-BE-NOVSX-LABEL: @i128_increment_by_val
153 ; CHECK-BE-NOVSX: addc 4, 4, 6
154 ; CHECK-BE-NOVSX-NEXT: adde 3, 3, 5
155 ; CHECK-BE-NOVSX: blr
156 }
157
158
159 ; Callsites for the routines defined above. 
160 ; Ensure the parameters are loaded in the same order that is expected by the 
161 ; callee. See comments for individual functions above for details on registers
162 ; used for parameters.
163 define <1 x i128> @call_v1i128_increment_by_one() nounwind {
164        %tmp = load <1 x i128>, <1 x i128>* @x, align 16
165        %ret = call <1 x i128> @v1i128_increment_by_one(<1 x i128> %tmp)
166        ret <1 x i128> %ret
167
168 ; CHECK-LE-LABEL: @call_v1i128_increment_by_one
169 ; CHECK-LE: lxvd2x [[PARAM:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
170 ; CHECK-LE: xxswapd 34, [[PARAM]]
171 ; CHECK-LE: bl v1i128_increment_by_one
172 ; CHECK-LE: blr
173
174 ; CHECK-BE-LABEL: @call_v1i128_increment_by_one
175 ; CHECK-BE: lxvw4x 34, {{[0-9]+}}, {{[0-9]+}}
176 ; CHECK-BE-NOT: xxswapd 34, {{[0-9]+}}
177 ; CHECK-BE: bl v1i128_increment_by_one
178 ; CHECK-BE: blr
179
180 ; CHECK-NOVSX-LABEL: @call_v1i128_increment_by_one
181 ; CHECK-NOVSX: lvx 2, {{[0-9]+}}, {{[0-9]+}}
182 ; CHECK-NOVSX-NOT: xxswapd {{[0-9]+}}, {{[0-9]+}}
183 ; CHECK-NOVSX: bl v1i128_increment_by_one
184 ; CHECK-NOVSX: blr
185 }
186
187 define <1 x i128> @call_v1i128_increment_by_val() nounwind {
188        %tmp = load <1 x i128>, <1 x i128>* @x, align 16
189        %tmp2 = load <1 x i128>, <1 x i128>* @y, align 16
190        %ret = call <1 x i128> @v1i128_increment_by_val(<1 x i128> %tmp, <1 x i128> %tmp2)
191        ret <1 x i128> %ret
192
193 ; CHECK-LE-LABEL: @call_v1i128_increment_by_val
194 ; CHECK-LE: lxvd2x [[PARAM1:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
195 ; CHECK-LE: lxvd2x [[PARAM2:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
196 ; CHECK-LE-DAG: xxswapd 34, [[PARAM1]]
197 ; CHECK-LE-DAG: xxswapd 35, [[PARAM2]]
198 ; CHECK-LE: bl v1i128_increment_by_val
199 ; CHECK-LE: blr
200
201 ; CHECK-BE-LABEL: @call_v1i128_increment_by_val
202
203
204 ; CHECK-BE-DAG: lxvw4x 35, {{[0-9]+}}, {{[0-9]+}}
205 ; CHECK-BE-NOT: xxswapd 34, {{[0-9]+}}
206 ; CHECK-BE-NOT: xxswapd 35, {{[0-9]+}}
207 ; CHECK-BE: bl v1i128_increment_by_val
208 ; CHECK-BE: blr
209
210 ; CHECK-NOVSX-LABEL: @call_v1i128_increment_by_val
211 ; CHECK-NOVSX-DAG: lvx 2, {{[0-9]+}}, {{[0-9]+}}
212 ; CHECK-NOVSX-DAG: lvx 3, {{[0-9]+}}, {{[0-9]+}}
213 ; CHECK-NOVSX-NOT: xxswapd 34, {{[0-9]+}}
214 ; CHECK-NOVSX-NOT: xxswapd 35, {{[0-9]+}}
215 ; CHECK-NOVSX: bl v1i128_increment_by_val
216 ; CHECK-NOVSX: blr
217
218 }
219
220 define i128 @call_i128_increment_by_one() nounwind {
221        %tmp = load i128, i128* @a, align 16
222        %ret = call i128 @i128_increment_by_one(i128 %tmp)
223        ret i128 %ret
224 ;       %ret4 = call i128 @i128_increment_by_val(i128 %tmp2, i128 %tmp2)
225 ; CHECK-LE-LABEL: @call_i128_increment_by_one
226 ; CHECK-LE-DAG: ld 3, 0([[BASEREG:[0-9]+]])
227 ; CHECK-LE-DAG: ld 4, 8([[BASEREG]])
228 ; CHECK-LE: bl i128_increment_by_one
229 ; CHECK-LE: blr
230
231 ; CHECK-BE-LABEL: @call_i128_increment_by_one
232 ; CHECK-BE-DAG: ld 3, 0([[BASEREG:[0-9]+]])
233 ; CHECK-BE-DAG: ld 4, 8([[BASEREG]])
234 ; CHECK-BE: bl i128_increment_by_one
235 ; CHECK-BE: blr
236
237 ; CHECK-NOVSX-LABEL: @call_i128_increment_by_one
238 ; CHECK-NOVSX-DAG: ld 3, 0([[BASEREG:[0-9]+]])
239 ; CHECK-NOVSX-DAG: ld 4, 8([[BASEREG]])
240 ; CHECK-NOVSX: bl i128_increment_by_one
241 ; CHECK-NOVSX: blr
242 }
243
244 define i128 @call_i128_increment_by_val() nounwind {
245        %tmp = load i128, i128* @a, align 16
246        %tmp2 = load i128, i128* @b, align 16
247        %ret = call i128 @i128_increment_by_val(i128 %tmp, i128 %tmp2)
248        ret i128 %ret
249 ; CHECK-LE-LABEL: @call_i128_increment_by_val
250 ; CHECK-LE-DAG: ld 3, 0([[P1BASEREG:[0-9]+]])
251 ; CHECK-LE-DAG: ld 4, 8([[P1BASEREG]])
252 ; CHECK-LE-DAG: ld 5, 0([[P2BASEREG:[0-9]+]])
253 ; CHECK-LE-DAG: ld 6, 8([[P2BASEREG]])
254 ; CHECK-LE: bl i128_increment_by_val
255 ; CHECK-LE: blr
256
257 ; CHECK-BE-LABEL: @call_i128_increment_by_val
258 ; CHECK-BE-DAG: ld 3, 0([[P1BASEREG:[0-9]+]])
259 ; CHECK-BE-DAG: ld 4, 8([[P1BASEREG]])
260 ; CHECK-BE-DAG: ld 5, 0([[P2BASEREG:[0-9]+]])
261 ; CHECK-BE-DAG: ld 6, 8([[P2BASEREG]])
262 ; CHECK-BE: bl i128_increment_by_val
263 ; CHECK-BE: blr
264
265 ; CHECK-NOVSX-LABEL: @call_i128_increment_by_val
266 ; CHECK-NOVSX-DAG: ld 3, 0([[P1BASEREG:[0-9]+]])
267 ; CHECK-NOVSX-DAG: ld 4, 8([[P1BASEREG]])
268 ; CHECK-NOVSX-DAG: ld 5, 0([[P2BASEREG:[0-9]+]])
269 ; CHECK-NOVSX-DAG: ld 6, 8([[P2BASEREG]])
270 ; CHECK-NOVSX: bl i128_increment_by_val
271 ; CHECK-NOVSX: blr
272 }
273
274