xref: /llvm-project/llvm/test/CodeGen/PowerPC/crsave.ll (revision 6b70c5d79fe44cbe01b0443454c6952c5b541585)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
2; RUN: llc -O0 -frame-pointer=all -mtriple=powerpc-unknown-linux-gnu -mcpu=g5 < %s | FileCheck %s -check-prefix=PPC32
3; RUN: llc -O0 -mtriple=powerpc64-unknown-linux-gnu -mcpu=g5 < %s | FileCheck %s -check-prefix=PPC64
4; RUN: llc -O0 -mtriple=powerpc64le-unknown-linux-gnu -verify-machineinstrs < %s | FileCheck %s -check-prefix=PPC64-ELFv2
5
6declare void @foo()
7
8define i32 @test_cr2() nounwind uwtable {
9; PPC32-LABEL: test_cr2:
10; PPC32:       # %bb.0: # %entry
11; PPC32-NEXT:    mflr 0
12; PPC32-NEXT:    stwu 1, -32(1)
13; PPC32-NEXT:    stw 31, 28(1)
14; PPC32-NEXT:    stw 0, 36(1)
15; PPC32-NEXT:    .cfi_def_cfa_offset 32
16; PPC32-NEXT:    .cfi_offset r31, -4
17; PPC32-NEXT:    .cfi_offset lr, 4
18; PPC32-NEXT:    mr 31, 1
19; PPC32-NEXT:    .cfi_def_cfa_register r31
20; PPC32-NEXT:    .cfi_offset cr2, -8
21; PPC32-NEXT:    mfcr 12
22; PPC32-NEXT:    stw 12, 24(31)
23; PPC32-NEXT:    li 3, 1
24; PPC32-NEXT:    li 4, 2
25; PPC32-NEXT:    li 5, 3
26; PPC32-NEXT:    li 6, 0
27; PPC32-NEXT:    #APP
28; PPC32-EMPTY:
29; PPC32-NEXT:    mtcr 6
30; PPC32-NEXT:    cmpw 2, 4, 3
31; PPC32-NEXT:    mfcr 3
32; PPC32-NEXT:    #NO_APP
33; PPC32-NEXT:    stw 3, 20(31)
34; PPC32-NEXT:    bl foo
35; PPC32-NEXT:    lwz 3, 20(31)
36; PPC32-NEXT:    lwz 12, 24(31)
37; PPC32-NEXT:    mtocrf 32, 12
38; PPC32-NEXT:    lwz 0, 36(1)
39; PPC32-NEXT:    lwz 31, 28(1)
40; PPC32-NEXT:    addi 1, 1, 32
41; PPC32-NEXT:    mtlr 0
42; PPC32-NEXT:    blr
43;
44; PPC64-LABEL: test_cr2:
45; PPC64:       # %bb.0: # %entry
46; PPC64-NEXT:    mflr 0
47; PPC64-NEXT:    mfcr 12
48; PPC64-NEXT:    stw 12, 8(1)
49; PPC64-NEXT:    stdu 1, -128(1)
50; PPC64-NEXT:    std 0, 144(1)
51; PPC64-NEXT:    .cfi_def_cfa_offset 128
52; PPC64-NEXT:    .cfi_offset lr, 16
53; PPC64-NEXT:    .cfi_offset cr2, 8
54; PPC64-NEXT:    li 3, 1
55; PPC64-NEXT:    li 4, 2
56; PPC64-NEXT:    li 5, 3
57; PPC64-NEXT:    li 6, 0
58; PPC64-NEXT:    #APP
59; PPC64-EMPTY:
60; PPC64-NEXT:    mtcr 6
61; PPC64-NEXT:    cmpw 2, 4, 3
62; PPC64-NEXT:    mfcr 3
63; PPC64-NEXT:    #NO_APP
64; PPC64-NEXT:    stw 3, 124(1)
65; PPC64-NEXT:    bl foo
66; PPC64-NEXT:    nop
67; PPC64-NEXT:    lwz 3, 124(1)
68; PPC64-NEXT:    addi 1, 1, 128
69; PPC64-NEXT:    ld 0, 16(1)
70; PPC64-NEXT:    lwz 12, 8(1)
71; PPC64-NEXT:    mtocrf 32, 12
72; PPC64-NEXT:    mtlr 0
73; PPC64-NEXT:    blr
74;
75; PPC64-ELFv2-LABEL: test_cr2:
76; PPC64-ELFv2:       # %bb.0: # %entry
77; PPC64-ELFv2-NEXT:    mflr 0
78; PPC64-ELFv2-NEXT:    mfocrf 12, 32
79; PPC64-ELFv2-NEXT:    stw 12, 8(1)
80; PPC64-ELFv2-NEXT:    stdu 1, -112(1)
81; PPC64-ELFv2-NEXT:    std 0, 128(1)
82; PPC64-ELFv2-NEXT:    .cfi_def_cfa_offset 112
83; PPC64-ELFv2-NEXT:    .cfi_offset lr, 16
84; PPC64-ELFv2-NEXT:    .cfi_offset cr2, 8
85; PPC64-ELFv2-NEXT:    li 3, 1
86; PPC64-ELFv2-NEXT:    li 4, 2
87; PPC64-ELFv2-NEXT:    li 5, 3
88; PPC64-ELFv2-NEXT:    li 6, 0
89; PPC64-ELFv2-NEXT:    #APP
90; PPC64-ELFv2-EMPTY:
91; PPC64-ELFv2-NEXT:    mtcr 6
92; PPC64-ELFv2-NEXT:    cmpw 2, 4, 3
93; PPC64-ELFv2-NEXT:    mfcr 3
94; PPC64-ELFv2-NEXT:    #NO_APP
95; PPC64-ELFv2-NEXT:    stw 3, 108(1)
96; PPC64-ELFv2-NEXT:    bl foo
97; PPC64-ELFv2-NEXT:    nop
98; PPC64-ELFv2-NEXT:    lwz 3, 108(1)
99; PPC64-ELFv2-NEXT:    addi 1, 1, 112
100; PPC64-ELFv2-NEXT:    ld 0, 16(1)
101; PPC64-ELFv2-NEXT:    lwz 12, 8(1)
102; PPC64-ELFv2-NEXT:    mtocrf 32, 12
103; PPC64-ELFv2-NEXT:    mtlr 0
104; PPC64-ELFv2-NEXT:    blr
105entry:
106  %ret = alloca i32, align 4
107  %0 = call i32 asm sideeffect "\0A\09mtcr $4\0A\09cmpw 2,$2,$1\0A\09mfcr $0", "=r,r,r,r,r,~{cr2}"(i32 1, i32 2, i32 3, i32 0) nounwind
108  store i32 %0, ptr %ret, align 4
109  call void @foo()
110  %1 = load i32, ptr %ret, align 4
111  ret i32 %1
112}
113
114define i32 @test_cr234() nounwind {
115; PPC32-LABEL: test_cr234:
116; PPC32:       # %bb.0: # %entry
117; PPC32-NEXT:    mflr 0
118; PPC32-NEXT:    stwu 1, -32(1)
119; PPC32-NEXT:    stw 31, 28(1)
120; PPC32-NEXT:    stw 0, 36(1)
121; PPC32-NEXT:    mr 31, 1
122; PPC32-NEXT:    mfcr 12
123; PPC32-NEXT:    stw 12, 24(31)
124; PPC32-NEXT:    li 3, 1
125; PPC32-NEXT:    li 4, 2
126; PPC32-NEXT:    li 5, 3
127; PPC32-NEXT:    li 6, 0
128; PPC32-NEXT:    #APP
129; PPC32-EMPTY:
130; PPC32-NEXT:    mtcr 6
131; PPC32-NEXT:    cmpw 2, 4, 3
132; PPC32-NEXT:    cmpw 3, 4, 4
133; PPC32-NEXT:    cmpw 4, 4, 5
134; PPC32-NEXT:    mfcr 3
135; PPC32-NEXT:    #NO_APP
136; PPC32-NEXT:    stw 3, 20(31)
137; PPC32-NEXT:    bl foo
138; PPC32-NEXT:    lwz 3, 20(31)
139; PPC32-NEXT:    lwz 12, 24(31)
140; PPC32-NEXT:    mtocrf 32, 12
141; PPC32-NEXT:    mtocrf 16, 12
142; PPC32-NEXT:    mtocrf 8, 12
143; PPC32-NEXT:    lwz 0, 36(1)
144; PPC32-NEXT:    lwz 31, 28(1)
145; PPC32-NEXT:    addi 1, 1, 32
146; PPC32-NEXT:    mtlr 0
147; PPC32-NEXT:    blr
148;
149; PPC64-LABEL: test_cr234:
150; PPC64:       # %bb.0: # %entry
151; PPC64-NEXT:    mflr 0
152; PPC64-NEXT:    mfcr 12
153; PPC64-NEXT:    stw 12, 8(1)
154; PPC64-NEXT:    stdu 1, -128(1)
155; PPC64-NEXT:    std 0, 144(1)
156; PPC64-NEXT:    li 3, 1
157; PPC64-NEXT:    li 4, 2
158; PPC64-NEXT:    li 5, 3
159; PPC64-NEXT:    li 6, 0
160; PPC64-NEXT:    #APP
161; PPC64-EMPTY:
162; PPC64-NEXT:    mtcr 6
163; PPC64-NEXT:    cmpw 2, 4, 3
164; PPC64-NEXT:    cmpw 3, 4, 4
165; PPC64-NEXT:    cmpw 4, 4, 5
166; PPC64-NEXT:    mfcr 3
167; PPC64-NEXT:    #NO_APP
168; PPC64-NEXT:    stw 3, 124(1)
169; PPC64-NEXT:    bl foo
170; PPC64-NEXT:    nop
171; PPC64-NEXT:    lwz 3, 124(1)
172; PPC64-NEXT:    addi 1, 1, 128
173; PPC64-NEXT:    ld 0, 16(1)
174; PPC64-NEXT:    lwz 12, 8(1)
175; PPC64-NEXT:    mtocrf 32, 12
176; PPC64-NEXT:    mtocrf 16, 12
177; PPC64-NEXT:    mtocrf 8, 12
178; PPC64-NEXT:    mtlr 0
179; PPC64-NEXT:    blr
180;
181; PPC64-ELFv2-LABEL: test_cr234:
182; PPC64-ELFv2:       # %bb.0: # %entry
183; PPC64-ELFv2-NEXT:    mflr 0
184; PPC64-ELFv2-NEXT:    mfcr 12
185; PPC64-ELFv2-NEXT:    stw 12, 8(1)
186; PPC64-ELFv2-NEXT:    stdu 1, -112(1)
187; PPC64-ELFv2-NEXT:    std 0, 128(1)
188; PPC64-ELFv2-NEXT:    li 3, 1
189; PPC64-ELFv2-NEXT:    li 4, 2
190; PPC64-ELFv2-NEXT:    li 5, 3
191; PPC64-ELFv2-NEXT:    li 6, 0
192; PPC64-ELFv2-NEXT:    #APP
193; PPC64-ELFv2-EMPTY:
194; PPC64-ELFv2-NEXT:    mtcr 6
195; PPC64-ELFv2-NEXT:    cmpw 2, 4, 3
196; PPC64-ELFv2-NEXT:    cmpw 3, 4, 4
197; PPC64-ELFv2-NEXT:    cmpw 4, 4, 5
198; PPC64-ELFv2-NEXT:    mfcr 3
199; PPC64-ELFv2-NEXT:    #NO_APP
200; PPC64-ELFv2-NEXT:    stw 3, 108(1)
201; PPC64-ELFv2-NEXT:    bl foo
202; PPC64-ELFv2-NEXT:    nop
203; PPC64-ELFv2-NEXT:    lwz 3, 108(1)
204; PPC64-ELFv2-NEXT:    addi 1, 1, 112
205; PPC64-ELFv2-NEXT:    ld 0, 16(1)
206; PPC64-ELFv2-NEXT:    lwz 12, 8(1)
207; PPC64-ELFv2-NEXT:    mtocrf 32, 12
208; PPC64-ELFv2-NEXT:    mtocrf 16, 12
209; PPC64-ELFv2-NEXT:    mtocrf 8, 12
210; PPC64-ELFv2-NEXT:    mtlr 0
211; PPC64-ELFv2-NEXT:    blr
212entry:
213  %ret = alloca i32, align 4
214  %0 = call i32 asm sideeffect "\0A\09mtcr $4\0A\09cmpw 2,$2,$1\0A\09cmpw 3,$2,$2\0A\09cmpw 4,$2,$3\0A\09mfcr $0", "=r,r,r,r,r,~{cr2},~{cr3},~{cr4}"(i32 1, i32 2, i32 3, i32 0) nounwind
215  store i32 %0, ptr %ret, align 4
216  call void @foo()
217  %1 = load i32, ptr %ret, align 4
218  ret i32 %1
219}
220
221; Generate mfocrf in prologue when we need to save 1 nonvolatile CR field
222define void @cloberOneNvCrField() {
223; PPC32-LABEL: cloberOneNvCrField:
224; PPC32:       # %bb.0: # %entry
225; PPC32-NEXT:    stwu 1, -32(1)
226; PPC32-NEXT:    stw 31, 28(1)
227; PPC32-NEXT:    .cfi_def_cfa_offset 32
228; PPC32-NEXT:    .cfi_offset r31, -4
229; PPC32-NEXT:    mr 31, 1
230; PPC32-NEXT:    .cfi_def_cfa_register r31
231; PPC32-NEXT:    .cfi_offset cr2, -8
232; PPC32-NEXT:    mfcr 12
233; PPC32-NEXT:    stw 12, 24(31)
234; PPC32-NEXT:    #APP
235; PPC32-NEXT:    # clobbers
236; PPC32-NEXT:    #NO_APP
237; PPC32-NEXT:    lwz 12, 24(31)
238; PPC32-NEXT:    mtocrf 32, 12
239; PPC32-NEXT:    lwz 31, 28(1)
240; PPC32-NEXT:    addi 1, 1, 32
241; PPC32-NEXT:    blr
242;
243; PPC64-LABEL: cloberOneNvCrField:
244; PPC64:       # %bb.0: # %entry
245; PPC64-NEXT:    mfcr 12
246; PPC64-NEXT:    stw 12, 8(1)
247; PPC64-NEXT:    #APP
248; PPC64-NEXT:    # clobbers
249; PPC64-NEXT:    #NO_APP
250; PPC64-NEXT:    lwz 12, 8(1)
251; PPC64-NEXT:    mtocrf 32, 12
252; PPC64-NEXT:    blr
253;
254; PPC64-ELFv2-LABEL: cloberOneNvCrField:
255; PPC64-ELFv2:       # %bb.0: # %entry
256; PPC64-ELFv2-NEXT:    mfocrf 12, 32
257; PPC64-ELFv2-NEXT:    stw 12, 8(1)
258; PPC64-ELFv2-NEXT:    #APP
259; PPC64-ELFv2-NEXT:    # clobbers
260; PPC64-ELFv2-NEXT:    #NO_APP
261; PPC64-ELFv2-NEXT:    lwz 12, 8(1)
262; PPC64-ELFv2-NEXT:    mtocrf 32, 12
263; PPC64-ELFv2-NEXT:    blr
264entry:
265  tail call void asm sideeffect "# clobbers", "~{cr2}"()
266  ret void
267}
268
269; Generate mfcr in prologue when we need to save all nonvolatile CR field
270define void @cloberAllNvCrField() {
271; PPC32-LABEL: cloberAllNvCrField:
272; PPC32:       # %bb.0: # %entry
273; PPC32-NEXT:    stwu 1, -32(1)
274; PPC32-NEXT:    stw 31, 28(1)
275; PPC32-NEXT:    .cfi_def_cfa_offset 32
276; PPC32-NEXT:    .cfi_offset r31, -4
277; PPC32-NEXT:    mr 31, 1
278; PPC32-NEXT:    .cfi_def_cfa_register r31
279; PPC32-NEXT:    .cfi_offset cr2, -8
280; PPC32-NEXT:    .cfi_offset cr3, -8
281; PPC32-NEXT:    .cfi_offset cr4, -8
282; PPC32-NEXT:    mfcr 12
283; PPC32-NEXT:    stw 12, 24(31)
284; PPC32-NEXT:    #APP
285; PPC32-NEXT:    # clobbers
286; PPC32-NEXT:    #NO_APP
287; PPC32-NEXT:    lwz 12, 24(31)
288; PPC32-NEXT:    mtocrf 32, 12
289; PPC32-NEXT:    mtocrf 16, 12
290; PPC32-NEXT:    mtocrf 8, 12
291; PPC32-NEXT:    lwz 31, 28(1)
292; PPC32-NEXT:    addi 1, 1, 32
293; PPC32-NEXT:    blr
294;
295; PPC64-LABEL: cloberAllNvCrField:
296; PPC64:       # %bb.0: # %entry
297; PPC64-NEXT:    mfcr 12
298; PPC64-NEXT:    stw 12, 8(1)
299; PPC64-NEXT:    #APP
300; PPC64-NEXT:    # clobbers
301; PPC64-NEXT:    #NO_APP
302; PPC64-NEXT:    lwz 12, 8(1)
303; PPC64-NEXT:    mtocrf 32, 12
304; PPC64-NEXT:    mtocrf 16, 12
305; PPC64-NEXT:    mtocrf 8, 12
306; PPC64-NEXT:    blr
307;
308; PPC64-ELFv2-LABEL: cloberAllNvCrField:
309; PPC64-ELFv2:       # %bb.0: # %entry
310; PPC64-ELFv2-NEXT:    mfcr 12
311; PPC64-ELFv2-NEXT:    stw 12, 8(1)
312; PPC64-ELFv2-NEXT:    #APP
313; PPC64-ELFv2-NEXT:    # clobbers
314; PPC64-ELFv2-NEXT:    #NO_APP
315; PPC64-ELFv2-NEXT:    lwz 12, 8(1)
316; PPC64-ELFv2-NEXT:    mtocrf 32, 12
317; PPC64-ELFv2-NEXT:    mtocrf 16, 12
318; PPC64-ELFv2-NEXT:    mtocrf 8, 12
319; PPC64-ELFv2-NEXT:    blr
320entry:
321  tail call void asm sideeffect "# clobbers", "~{cr2},~{cr3},~{cr4}"()
322  ret void
323}
324