1; RUN: llc -march=mipsel   -mcpu=mips32   < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS32R1
2; RUN: llc -march=mipsel   -mcpu=mips32r2 < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS32R2
3; RUN: llc -march=mipsel   -mcpu=mips32r6 < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS32R6
4; RUN: llc -march=mips64el -mcpu=mips4    -mattr=n64 < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS4
5; RUN: llc -march=mips64el -mcpu=mips64   -mattr=n64 < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS4
6; RUN: llc -march=mips64el -mcpu=mips64r2 -mattr=n64 < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS4
7; RUN: llc -march=mips64el -mcpu=mips64r6 -mattr=n64 < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS64R6
8
9; Check that [ls][dwu]xc1 are not emitted for nacl.
10; RUN: llc -mtriple=mipsel-none-nacl-gnu -mcpu=mips32r2 < %s | FileCheck %s -check-prefix=CHECK-NACL
11
12%struct.S = type <{ [4 x float] }>
13%struct.S2 = type <{ [4 x double] }>
14%struct.S3 = type <{ i8, float }>
15
16@s = external global [4 x %struct.S]
17@gf = external global float
18@gd = external global double
19@s2 = external global [4 x %struct.S2]
20@s3 = external global %struct.S3
21
22define float @foo0(float* nocapture %b, i32 %o) nounwind readonly {
23entry:
24; ALL-LABEL: foo0:
25
26; MIPS32R1:      sll $[[T1:[0-9]+]], $5, 2
27; MIPS32R1:      addu $[[T3:[0-9]+]], $4, $[[T1]]
28; MIPS32R1:      lwc1 $f0, 0($[[T3]])
29
30; MIPS32R2:      sll $[[T1:[0-9]+]], $5, 2
31; MIPS32R2:      lwxc1 $f0, $[[T1]]($4)
32
33; MIPS32R6:      sll $[[T1:[0-9]+]], $5, 2
34; MIPS32R6:      addu $[[T3:[0-9]+]], $4, $[[T1]]
35; MIPS32R6:      lwc1 $f0, 0($[[T3]])
36
37; MIPS4:         sll $[[T0:[0-9]+]], $5, 0
38; MIPS4:         dsll $[[T1:[0-9]+]], $[[T0]], 2
39; MIPS4:         lwxc1 $f0, $[[T1]]($4)
40
41; MIPS64R6:      sll $[[T0:[0-9]+]], $5, 0
42; MIPS64R6:      dsll $[[T1:[0-9]+]], $[[T0]], 2
43; MIPS64R6:      daddu $[[T3:[0-9]+]], $4, $[[T1]]
44; MIPS64R6:      lwc1 $f0, 0($[[T3]])
45
46; CHECK-NACL-NOT: lwxc1
47
48  %arrayidx = getelementptr inbounds float* %b, i32 %o
49  %0 = load float* %arrayidx, align 4
50  ret float %0
51}
52
53define double @foo1(double* nocapture %b, i32 %o) nounwind readonly {
54entry:
55; ALL-LABEL: foo1:
56
57; MIPS32R1:      sll $[[T1:[0-9]+]], $5, 3
58; MIPS32R1:      addu $[[T3:[0-9]+]], $4, $[[T1]]
59; MIPS32R1:      ldc1 $f0, 0($[[T3]])
60
61; MIPS32R2:      sll $[[T1:[0-9]+]], $5, 3
62; MIPS32R2:      ldxc1 $f0, $[[T1]]($4)
63
64; MIPS32R6:      sll $[[T1:[0-9]+]], $5, 3
65; MIPS32R6:      addu $[[T3:[0-9]+]], $4, $[[T1]]
66; MIPS32R6:      ldc1 $f0, 0($[[T3]])
67
68; MIPS4:         sll $[[T0:[0-9]+]], $5, 0
69; MIPS4:         dsll $[[T1:[0-9]+]], $[[T0]], 3
70; MIPS4:         ldxc1 $f0, $[[T1]]($4)
71
72; MIPS64R6:      sll $[[T0:[0-9]+]], $5, 0
73; MIPS64R6:      dsll $[[T1:[0-9]+]], $[[T0]], 3
74; MIPS64R6:      daddu $[[T3:[0-9]+]], $4, $[[T1]]
75; MIPS64R6:      ldc1 $f0, 0($[[T3]])
76
77; CHECK-NACL-NOT: ldxc1
78
79  %arrayidx = getelementptr inbounds double* %b, i32 %o
80  %0 = load double* %arrayidx, align 8
81  ret double %0
82}
83
84define float @foo2(i32 %b, i32 %c) nounwind readonly {
85entry:
86; ALL-LABEL: foo2:
87
88; luxc1 did not exist in MIPS32r1
89; MIPS32R1-NOT:  luxc1
90
91; luxc1 is a misnomer since it aligns the given pointer downwards and performs
92; an aligned load. We mustn't use it to handle unaligned loads.
93; MIPS32R2-NOT:  luxc1
94
95; luxc1 was removed in MIPS32r6
96; MIPS32R6-NOT:  luxc1
97
98; MIPS4-NOT:     luxc1
99
100; luxc1 was removed in MIPS64r6
101; MIPS64R6-NOT:  luxc1
102
103  %arrayidx1 = getelementptr inbounds [4 x %struct.S]* @s, i32 0, i32 %b, i32 0, i32 %c
104  %0 = load float* %arrayidx1, align 1
105  ret float %0
106}
107
108define void @foo3(float* nocapture %b, i32 %o) nounwind {
109entry:
110; ALL-LABEL: foo3:
111
112; MIPS32R1-DAG:  lwc1 $[[T0:f0]], 0(${{[0-9]+}})
113; MIPS32R1-DAG:  addu $[[T1:[0-9]+]], $4, ${{[0-9]+}}
114; MIPS32R1-DAG:  swc1 $[[T0]], 0($[[T1]])
115
116; MIPS32R2:      lwc1 $[[T0:f0]], 0(${{[0-9]+}})
117; MIPS32R2:      swxc1 $[[T0]], ${{[0-9]+}}($4)
118
119; MIPS32R6-DAG:  lwc1 $[[T0:f0]], 0(${{[0-9]+}})
120; MIPS32R6-DAG:  addu $[[T1:[0-9]+]], $4, ${{[0-9]+}}
121; MIPS32R6-DAG:  swc1 $[[T0]], 0($[[T1]])
122
123; MIPS4:         lwc1 $[[T0:f0]], 0(${{[0-9]+}})
124; MIPS4:         swxc1 $[[T0]], ${{[0-9]+}}($4)
125
126; MIPS64R6-DAG:  lwc1 $[[T0:f0]], 0(${{[0-9]+}})
127; MIPS64R6-DAG:  daddu $[[T1:[0-9]+]], $4, ${{[0-9]+}}
128; MIPS64R6-DAG:  swc1 $[[T0]], 0($[[T1]])
129
130; CHECK-NACL-NOT: swxc1
131
132  %0 = load float* @gf, align 4
133  %arrayidx = getelementptr inbounds float* %b, i32 %o
134  store float %0, float* %arrayidx, align 4
135  ret void
136}
137
138define void @foo4(double* nocapture %b, i32 %o) nounwind {
139entry:
140; ALL-LABEL: foo4:
141
142; MIPS32R1-DAG:  ldc1 $[[T0:f0]], 0(${{[0-9]+}})
143; MIPS32R1-DAG:  addu $[[T1:[0-9]+]], $4, ${{[0-9]+}}
144; MIPS32R1-DAG:  sdc1 $[[T0]], 0($[[T1]])
145
146; MIPS32R2:      ldc1 $[[T0:f0]], 0(${{[0-9]+}})
147; MIPS32R2:      sdxc1 $[[T0]], ${{[0-9]+}}($4)
148
149; MIPS32R6-DAG:  ldc1 $[[T0:f0]], 0(${{[0-9]+}})
150; MIPS32R6-DAG:  addu $[[T1:[0-9]+]], $4, ${{[0-9]+}}
151; MIPS32R6-DAG:  sdc1 $[[T0]], 0($[[T1]])
152
153; MIPS4:         ldc1 $[[T0:f0]], 0(${{[0-9]+}})
154; MIPS4:         sdxc1 $[[T0]], ${{[0-9]+}}($4)
155
156; MIPS64R6-DAG:  ldc1 $[[T0:f0]], 0(${{[0-9]+}})
157; MIPS64R6-DAG:  daddu $[[T1:[0-9]+]], $4, ${{[0-9]+}}
158; MIPS64R6-DAG:  sdc1 $[[T0]], 0($[[T1]])
159
160; CHECK-NACL-NOT: sdxc1
161
162  %0 = load double* @gd, align 8
163  %arrayidx = getelementptr inbounds double* %b, i32 %o
164  store double %0, double* %arrayidx, align 8
165  ret void
166}
167
168define void @foo5(i32 %b, i32 %c) nounwind {
169entry:
170; ALL-LABEL: foo5:
171
172; MIPS32R1-NOT:  suxc1
173
174; MIPS32R2-NOT:  suxc1
175
176; MIPS32R6-NOT:  suxc1
177
178; MIPS4-NOT:     suxc1
179
180; MIPS64R6-NOT:  suxc1
181
182  %0 = load float* @gf, align 4
183  %arrayidx1 = getelementptr inbounds [4 x %struct.S]* @s, i32 0, i32 %b, i32 0, i32 %c
184  store float %0, float* %arrayidx1, align 1
185  ret void
186}
187
188define double @foo6(i32 %b, i32 %c) nounwind readonly {
189entry:
190; ALL-LABEL: foo6:
191
192; MIPS32R1-NOT:  luxc1
193
194; MIPS32R2-NOT:  luxc1
195
196; MIPS32R6-NOT:  luxc1
197
198; MIPS4-NOT:     luxc1
199
200; MIPS64R6-NOT:  luxc1
201
202  %arrayidx1 = getelementptr inbounds [4 x %struct.S2]* @s2, i32 0, i32 %b, i32 0, i32 %c
203  %0 = load double* %arrayidx1, align 1
204  ret double %0
205}
206
207define void @foo7(i32 %b, i32 %c) nounwind {
208entry:
209; ALL-LABEL: foo7:
210
211; MIPS32R1-NOT:  suxc1
212
213; MIPS32R2-NOT:  suxc1
214
215; MIPS32R6-NOT:  suxc1
216
217; MIPS4-NOT:     suxc1
218
219; MIPS64R6-NOT:  suxc1
220
221  %0 = load double* @gd, align 8
222  %arrayidx1 = getelementptr inbounds [4 x %struct.S2]* @s2, i32 0, i32 %b, i32 0, i32 %c
223  store double %0, double* %arrayidx1, align 1
224  ret void
225}
226
227define float @foo8() nounwind readonly {
228entry:
229; ALL-LABEL: foo8:
230
231; MIPS32R1-NOT:  luxc1
232
233; MIPS32R2-NOT:  luxc1
234
235; MIPS32R6-NOT:  luxc1
236
237; MIPS4-NOT:     luxc1
238
239; MIPS64R6-NOT:  luxc1
240
241  %0 = load float* getelementptr inbounds (%struct.S3* @s3, i32 0, i32 1), align 1
242  ret float %0
243}
244
245define void @foo9(float %f) nounwind {
246entry:
247; ALL-LABEL: foo9:
248
249; MIPS32R1-NOT:  suxc1
250
251; MIPS32R2-NOT:  suxc1
252
253; MIPS32R6-NOT:  suxc1
254
255; MIPS4-NOT:     suxc1
256
257; MIPS64R6-NOT:  suxc1
258
259  store float %f, float* getelementptr inbounds (%struct.S3* @s3, i32 0, i32 1), align 1
260  ret void
261}
262
263