1; RUN: llc -mtriple=thumbv7m -mattr=+dsp %s -o - | FileCheck %s
2; RUN: llc -mtriple=armv7a %s -o - | FileCheck %s
3; RUN: llc -mtriple=thumbv7m -mattr=-dsp %s -o - | FileCheck --check-prefix=NODSP %s
4
5define hidden i32 @SMMULR_SMMLAR(i32 %a, i32 %b0, i32 %b1, i32 %Xn, i32 %Xn1) local_unnamed_addr {
6entry:
7; CHECK-LABEL: SMMULR_SMMLAR:
8; CHECK: ldr r0, [sp]
9; CHECK-NEXT: smmulr r0, {{(r0, r2|r2, r0)}}
10; CHECK-NEXT: smmlar r0, {{(r1, r3|r3, r1)}}, r0
11; NODSP-LABEL: SMMULR_SMMLAR:
12; NODSP-NOT: smmulr
13; NODSP-NOT: smmlar
14  %conv = sext i32 %b1 to i64
15  %conv1 = sext i32 %Xn1 to i64
16  %mul = mul nsw i64 %conv1, %conv
17  %add = add nsw i64 %mul, 2147483648
18  %0 = and i64 %add, -4294967296
19  %conv4 = sext i32 %b0 to i64
20  %conv5 = sext i32 %Xn to i64
21  %mul6 = mul nsw i64 %conv5, %conv4
22  %add7 = add i64 %mul6, 2147483648
23  %add8 = add i64 %add7, %0
24  %1 = lshr i64 %add8, 32
25  %conv10 = trunc i64 %1 to i32
26  ret i32 %conv10
27}
28
29define hidden i32 @SMMULR(i32 %a, i32 %b) local_unnamed_addr {
30entry:
31; CHECK-LABEL: SMMULR:
32; CHECK: smmulr r0, {{(r0, r1|r1, r0)}}
33; NODSP-LABEL: SMMULR:
34; NODSP-NOT: smmulr
35  %conv = sext i32 %a to i64
36  %conv1 = sext i32 %b to i64
37  %mul = mul nsw i64 %conv1, %conv
38  %add = add nsw i64 %mul, 2147483648
39  %0 = lshr i64 %add, 32
40  %conv2 = trunc i64 %0 to i32
41  ret i32 %conv2
42}
43
44define hidden i32 @SMMUL(i32 %a, i32 %b) local_unnamed_addr {
45entry:
46; CHECK-LABEL: SMMUL:
47; CHECK: smmul r0, {{(r0, r1|r1, r0)}}
48; NODSP-LABEL: SMMUL:
49; NODSP-NOT: smmul
50  %conv = sext i32 %a to i64
51  %conv1 = sext i32 %b to i64
52  %mul = mul nsw i64 %conv1, %conv
53  %0 = lshr i64 %mul, 32
54  %conv2 = trunc i64 %0 to i32
55  ret i32 %conv2
56}
57
58define hidden i32 @SMMLSR(i32 %a, i32 %b, i32 %c) local_unnamed_addr {
59entry:
60; CHECK-LABEL: SMMLSR:
61; CHECK: smmlsr r0, {{(r1, r2|r2, r1)}}, r0
62; NODSP-LABEL: SMMLSR:
63; NODSP-NOT: smmlsr
64  %conv6 = zext i32 %a to i64
65  %shl = shl nuw i64 %conv6, 32
66  %conv1 = sext i32 %b to i64
67  %conv2 = sext i32 %c to i64
68  %mul = mul nsw i64 %conv2, %conv1
69  %sub = or i64 %shl, 2147483648
70  %add = sub i64 %sub, %mul
71  %0 = lshr i64 %add, 32
72  %conv3 = trunc i64 %0 to i32
73  ret i32 %conv3
74}
75
76define hidden i32 @NOT_SMMLSR(i32 %a, i32 %b, i32 %c) local_unnamed_addr {
77entry:
78; CHECK-LABEL: NOT_SMMLSR:
79; CHECK-NOT: smmlsr
80; NODSP-LABEL: NOT_SMMLSR:
81; NODSP-NOT: smmlsr
82  %conv = sext i32 %b to i64
83  %conv1 = sext i32 %c to i64
84  %mul = mul nsw i64 %conv1, %conv
85  %add = add nsw i64 %mul, 2147483648
86  %0 = lshr i64 %add, 32
87  %conv2 = trunc i64 %0 to i32
88  %sub = sub nsw i32 %a, %conv2
89  ret i32 %sub
90}
91
92define hidden i32 @SMMLS(i32 %a, i32 %b, i32 %c) local_unnamed_addr {
93entry:
94; CHECK-LABEL: SMMLS:
95; CHECK: smmls r0, {{(r1, r2|r2, r1)}}, r0
96; NODSP-LABEL: SMMLS:
97; NODSP-NOT: smmls
98  %conv5 = zext i32 %a to i64
99  %shl = shl nuw i64 %conv5, 32
100  %conv1 = sext i32 %b to i64
101  %conv2 = sext i32 %c to i64
102  %mul = mul nsw i64 %conv2, %conv1
103  %sub = sub nsw i64 %shl, %mul
104  %0 = lshr i64 %sub, 32
105  %conv3 = trunc i64 %0 to i32
106  ret i32 %conv3
107}
108
109define hidden i32 @NOT_SMMLS(i32 %a, i32 %b, i32 %c) local_unnamed_addr {
110entry:
111; CHECK-LABEL: NOT_SMMLS:
112; CHECK-NOT: smmls
113; NODSP-LABEL: NOT_SMMLS:
114; NODSP-NOT: smmls
115  %conv = sext i32 %b to i64
116  %conv1 = sext i32 %c to i64
117  %mul = mul nsw i64 %conv1, %conv
118  %0 = lshr i64 %mul, 32
119  %conv2 = trunc i64 %0 to i32
120  %sub = sub nsw i32 %a, %conv2
121  ret i32 %sub
122}
123
124define hidden i32 @SMMLA(i32 %a, i32 %b, i32 %c) local_unnamed_addr {
125entry:
126; CHECK-LABEL: SMMLA:
127; CHECK: smmla r0, {{(r1, r2|r2, r1)}}, r0
128; NODSP-LABEL: SMMLA:
129; NODSP-NOT: smmla
130  %conv = sext i32 %b to i64
131  %conv1 = sext i32 %c to i64
132  %mul = mul nsw i64 %conv1, %conv
133  %0 = lshr i64 %mul, 32
134  %conv2 = trunc i64 %0 to i32
135  %add = add nsw i32 %conv2, %a
136  ret i32 %add
137}
138
139define hidden i32 @SMMLAR(i32 %a, i32 %b, i32 %c) local_unnamed_addr {
140entry:
141; CHECK-LABEL: SMMLAR:
142; CHECK: smmlar r0, {{(r1, r2|r2, r1)}}, r0
143; NODSP-LABEL: SMMLAR:
144; NODSP-NOT: smmlar
145  %conv7 = zext i32 %a to i64
146  %shl = shl nuw i64 %conv7, 32
147  %conv1 = sext i32 %b to i64
148  %conv2 = sext i32 %c to i64
149  %mul = mul nsw i64 %conv2, %conv1
150  %add = or i64 %shl, 2147483648
151  %add3 = add i64 %add, %mul
152  %0 = lshr i64 %add3, 32
153  %conv4 = trunc i64 %0 to i32
154  ret i32 %conv4
155}
156
157define hidden i32 @NOT_SMMLA(i32 %a, i32 %b, i32 %c) local_unnamed_addr {
158entry:
159; CHECK-LABEL: NOT_SMMLA:
160; CHECK-NOT: smmla
161; NODSP-LABEL: NOT_SMMLA:
162; NODSP-NOT: smmla
163  %conv = sext i32 %b to i64
164  %conv1 = sext i32 %c to i64
165  %mul = mul nsw i64 %conv1, %conv
166  %0 = lshr i64 %mul, 32
167  %conv2 = trunc i64 %0 to i32
168  %add = xor i32 %conv2, -2147483648
169  %add3 = add i32 %add, %a
170  ret i32 %add3
171}
172