1; RUN: llc -march=mips < %s | FileCheck --check-prefix=ALL --check-prefix=O32 %s
2; RUN: llc -march=mipsel < %s | FileCheck --check-prefix=ALL --check-prefix=O32 %s
3; RUN: llc -march=mips < %s | FileCheck --check-prefix=ALL --check-prefix=O32-INV %s
4; RUN: llc -march=mipsel < %s | FileCheck --check-prefix=ALL --check-prefix=O32-INV %s
5
6; RUN-TODO: llc -march=mips64 -target-abi o32 < %s | FileCheck --check-prefix=ALL --check-prefix=O32 %s
7; RUN-TODO: llc -march=mips64el -target-abi o32 < %s | FileCheck --check-prefix=ALL --check-prefix=O32 %s
8; RUN-TODO: llc -march=mips64 -target-abi o32 < %s | FileCheck --check-prefix=ALL --check-prefix=O32-INV %s
9; RUN-TODO: llc -march=mips64el -target-abi o32 < %s | FileCheck --check-prefix=ALL --check-prefix=O32-INV %s
10
11; RUN: llc -march=mips64 -target-abi n32 < %s | FileCheck --check-prefix=ALL --check-prefix=N32 %s
12; RUN: llc -march=mips64el -target-abi n32 < %s | FileCheck --check-prefix=ALL --check-prefix=N32 %s
13; RUN: llc -march=mips64 -target-abi n32 < %s | FileCheck --check-prefix=ALL --check-prefix=N32-INV %s
14; RUN: llc -march=mips64el -target-abi n32 < %s | FileCheck --check-prefix=ALL --check-prefix=N32-INV %s
15
16; RUN: llc -march=mips64 -target-abi n64 < %s | FileCheck --check-prefix=ALL --check-prefix=N64 %s
17; RUN: llc -march=mips64el -target-abi n64 < %s | FileCheck --check-prefix=ALL --check-prefix=N64 %s
18; RUN: llc -march=mips64 -target-abi n64 < %s | FileCheck --check-prefix=ALL --check-prefix=N64-INV %s
19; RUN: llc -march=mips64el -target-abi n64 < %s | FileCheck --check-prefix=ALL --check-prefix=N64-INV %s
20
21; Test the the callee-saved registers are callee-saved as specified by section
22; 2 of the MIPSpro N32 Handbook and section 3 of the SYSV ABI spec.
23
24define void @gpr_clobber() nounwind {
25entry:
26        ; Clobbering the stack pointer is a bad idea so we'll skip that one
27        call void asm "# Clobber", "~{$0},~{$1},~{$2},~{$3},~{$4},~{$5},~{$6},~{$7},~{$8},~{$9},~{$10},~{$11},~{$12},~{$13},~{$14},~{$15},~{$16},~{$17},~{$18},~{$19},~{$20},~{$21},~{$22},~{$23},~{$24},~{$25},~{$26},~{$27},~{$28},~{$30},~{$31}"()
28        ret void
29}
30
31; ALL-LABEL: gpr_clobber:
32; O32:           addiu $sp, $sp, -40
33; O32-INV-NOT:   sw $0,
34; O32-INV-NOT:   sw $1,
35; O32-INV-NOT:   sw $2,
36; O32-INV-NOT:   sw $3,
37; O32-INV-NOT:   sw $4,
38; O32-INV-NOT:   sw $5,
39; O32-INV-NOT:   sw $6,
40; O32-INV-NOT:   sw $7,
41; O32-INV-NOT:   sw $8,
42; O32-INV-NOT:   sw $9,
43; O32-INV-NOT:   sw $10,
44; O32-INV-NOT:   sw $11,
45; O32-INV-NOT:   sw $12,
46; O32-INV-NOT:   sw $13,
47; O32-INV-NOT:   sw $14,
48; O32-INV-NOT:   sw $15,
49; O32-DAG:       sw [[G16:\$16]], [[OFF16:[0-9]+]]($sp)
50; O32-DAG:       sw [[G17:\$17]], [[OFF17:[0-9]+]]($sp)
51; O32-DAG:       sw [[G18:\$18]], [[OFF18:[0-9]+]]($sp)
52; O32-DAG:       sw [[G19:\$19]], [[OFF19:[0-9]+]]($sp)
53; O32-DAG:       sw [[G20:\$20]], [[OFF20:[0-9]+]]($sp)
54; O32-DAG:       sw [[G21:\$21]], [[OFF21:[0-9]+]]($sp)
55; O32-DAG:       sw [[G22:\$22]], [[OFF22:[0-9]+]]($sp)
56; O32-DAG:       sw [[G23:\$23]], [[OFF23:[0-9]+]]($sp)
57; O32-INV-NOT:   sw $24,
58; O32-INV-NOT:   sw $25,
59; O32-INV-NOT:   sw $26,
60; O32-INV-NOT:   sw $27,
61; O32-INV-NOT:   sw $28,
62; O32-INV-NOT:   sw $29,
63; O32-DAG:       sw [[G30:\$fp]], [[OFF30:[0-9]+]]($sp)
64; O32-DAG:       sw [[G31:\$fp]], [[OFF31:[0-9]+]]($sp)
65; O32-DAG:       lw [[G16]], [[OFF16]]($sp)
66; O32-DAG:       lw [[G17]], [[OFF17]]($sp)
67; O32-DAG:       lw [[G18]], [[OFF18]]($sp)
68; O32-DAG:       lw [[G19]], [[OFF19]]($sp)
69; O32-DAG:       lw [[G20]], [[OFF20]]($sp)
70; O32-DAG:       lw [[G21]], [[OFF21]]($sp)
71; O32-DAG:       lw [[G22]], [[OFF22]]($sp)
72; O32-DAG:       lw [[G23]], [[OFF23]]($sp)
73; O32-DAG:       lw [[G30]], [[OFF30]]($sp)
74; O32-DAG:       lw [[G31]], [[OFF31]]($sp)
75; O32:           addiu $sp, $sp, 40
76
77; N32:           addiu $sp, $sp, -96
78; N32-INV-NOT:   sd $0,
79; N32-INV-NOT:   sd $1,
80; N32-INV-NOT:   sd $2,
81; N32-INV-NOT:   sd $3,
82; N32-INV-NOT:   sd $4,
83; N32-INV-NOT:   sd $5,
84; N32-INV-NOT:   sd $6,
85; N32-INV-NOT:   sd $7,
86; N32-INV-NOT:   sd $8,
87; N32-INV-NOT:   sd $9,
88; N32-INV-NOT:   sd $10,
89; N32-INV-NOT:   sd $11,
90; N32-INV-NOT:   sd $12,
91; N32-INV-NOT:   sd $13,
92; N32-INV-NOT:   sd $14,
93; N32-INV-NOT:   sd $15,
94; N32-DAG:       sd [[G16:\$16]], [[OFF16:[0-9]+]]($sp)
95; N32-DAG:       sd [[G17:\$17]], [[OFF17:[0-9]+]]($sp)
96; N32-DAG:       sd [[G18:\$18]], [[OFF18:[0-9]+]]($sp)
97; N32-DAG:       sd [[G19:\$19]], [[OFF19:[0-9]+]]($sp)
98; N32-DAG:       sd [[G20:\$20]], [[OFF20:[0-9]+]]($sp)
99; N32-DAG:       sd [[G21:\$21]], [[OFF21:[0-9]+]]($sp)
100; N32-DAG:       sd [[G22:\$22]], [[OFF22:[0-9]+]]($sp)
101; N32-DAG:       sd [[G23:\$23]], [[OFF23:[0-9]+]]($sp)
102; N32-INV-NOT:   sd $24,
103; N32-INV-NOT:   sd $25,
104; N32-INV-NOT:   sd $26,
105; N32-INV-NOT:   sd $27,
106; N32-DAG:       sd [[G28:\$gp]], [[OFF28:[0-9]+]]($sp)
107; N32-INV-NOT:   sd $29,
108; N32-DAG:       sd [[G30:\$fp]], [[OFF30:[0-9]+]]($sp)
109; N32-DAG:       sd [[G31:\$fp]], [[OFF31:[0-9]+]]($sp)
110; N32-DAG:       ld [[G16]], [[OFF16]]($sp)
111; N32-DAG:       ld [[G17]], [[OFF17]]($sp)
112; N32-DAG:       ld [[G18]], [[OFF18]]($sp)
113; N32-DAG:       ld [[G19]], [[OFF19]]($sp)
114; N32-DAG:       ld [[G20]], [[OFF20]]($sp)
115; N32-DAG:       ld [[G21]], [[OFF21]]($sp)
116; N32-DAG:       ld [[G22]], [[OFF22]]($sp)
117; N32-DAG:       ld [[G23]], [[OFF23]]($sp)
118; N32-DAG:       ld [[G28]], [[OFF28]]($sp)
119; N32-DAG:       ld [[G30]], [[OFF30]]($sp)
120; N32-DAG:       ld [[G31]], [[OFF31]]($sp)
121; N32:           addiu $sp, $sp, 96
122
123; N64:           daddiu $sp, $sp, -96
124; N64-INV-NOT:   sd $0,
125; N64-INV-NOT:   sd $1,
126; N64-INV-NOT:   sd $2,
127; N64-INV-NOT:   sd $3,
128; N64-INV-NOT:   sd $4,
129; N64-INV-NOT:   sd $5,
130; N64-INV-NOT:   sd $6,
131; N64-INV-NOT:   sd $7,
132; N64-INV-NOT:   sd $8,
133; N64-INV-NOT:   sd $9,
134; N64-INV-NOT:   sd $10,
135; N64-INV-NOT:   sd $11,
136; N64-INV-NOT:   sd $12,
137; N64-INV-NOT:   sd $13,
138; N64-INV-NOT:   sd $14,
139; N64-INV-NOT:   sd $15,
140; N64-DAG:       sd [[G16:\$16]], [[OFF16:[0-9]+]]($sp)
141; N64-DAG:       sd [[G17:\$17]], [[OFF17:[0-9]+]]($sp)
142; N64-DAG:       sd [[G18:\$18]], [[OFF18:[0-9]+]]($sp)
143; N64-DAG:       sd [[G19:\$19]], [[OFF19:[0-9]+]]($sp)
144; N64-DAG:       sd [[G20:\$20]], [[OFF20:[0-9]+]]($sp)
145; N64-DAG:       sd [[G21:\$21]], [[OFF21:[0-9]+]]($sp)
146; N64-DAG:       sd [[G22:\$22]], [[OFF22:[0-9]+]]($sp)
147; N64-DAG:       sd [[G23:\$23]], [[OFF23:[0-9]+]]($sp)
148; N64-DAG:       sd [[G30:\$fp]], [[OFF30:[0-9]+]]($sp)
149; N64-DAG:       sd [[G31:\$fp]], [[OFF31:[0-9]+]]($sp)
150; N64-INV-NOT:   sd $24,
151; N64-INV-NOT:   sd $25,
152; N64-INV-NOT:   sd $26,
153; N64-INV-NOT:   sd $27,
154; N64-DAG:       sd [[G28:\$gp]], [[OFF28:[0-9]+]]($sp)
155; N64-INV-NOT:   sd $29,
156; N64-DAG:       ld [[G16]], [[OFF16]]($sp)
157; N64-DAG:       ld [[G17]], [[OFF17]]($sp)
158; N64-DAG:       ld [[G18]], [[OFF18]]($sp)
159; N64-DAG:       ld [[G19]], [[OFF19]]($sp)
160; N64-DAG:       ld [[G20]], [[OFF20]]($sp)
161; N64-DAG:       ld [[G21]], [[OFF21]]($sp)
162; N64-DAG:       ld [[G22]], [[OFF22]]($sp)
163; N64-DAG:       ld [[G23]], [[OFF23]]($sp)
164; N64-DAG:       ld [[G28]], [[OFF28]]($sp)
165; N64-DAG:       ld [[G30]], [[OFF30]]($sp)
166; N64-DAG:       ld [[G31]], [[OFF31]]($sp)
167; N64:           daddiu $sp, $sp, 96
168