1 // REQUIRES: arm-registered-target
2 
3 // RUN: %clang_cc1 -triple armv6 -verify=arm6 %s
4 // RUN: %clang_cc1 -triple armv7 -verify=arm7 %s
5 // RUN: %clang_cc1 -triple thumbv6 -verify=thumb1 %s
6 // RUN: %clang_cc1 -triple thumbv7 -verify=thumb2 %s
7 
8 // j: An immediate integer between 0 and 65535 (valid for MOVW) (ARM/Thumb2)
test_j(int i)9 int test_j(int i) {
10   int res;
11   __asm("movw %0, %1;"
12         : [ result ] "=r"(res)
13         : [ constant ] "j"(-1), [ input ] "r"(i)
14         :);
15   // arm6-error@13 {{invalid input constraint 'j' in asm}}
16   // arm7-error@13 {{value '-1' out of range for constraint 'j'}}
17   // thumb1-error@13 {{invalid input constraint 'j' in asm}}
18   // thumb2-error@13 {{value '-1' out of range for constraint 'j'}}
19   __asm("movw %0, %1;"
20         : [ result ] "=r"(res)
21         : [ constant ] "j"(0), [ input ] "r"(i)
22         :);
23   // arm6-error@21 {{invalid input constraint 'j' in asm}}
24   // arm7-no-error
25   // thumb1-error@21 {{invalid input constraint 'j' in asm}}
26   // thumb2-no-error
27   __asm("movw %0, %1;"
28         : [ result ] "=r"(res)
29         : [ constant ] "j"(65535), [ input ] "r"(i)
30         :);
31   // arm6-error@29 {{invalid input constraint 'j' in asm}}
32   // arm7-no-error
33   // thumb1-error@29 {{invalid input constraint 'j' in asm}}
34   // thumb2-no-error
35   __asm("movw %0, %1;"
36         : [ result ] "=r"(res)
37         : [ constant ] "j"(65536), [ input ] "r"(i)
38         :);
39   // arm6-error@37 {{invalid input constraint 'j' in asm}}
40   // arm7-error@37 {{value '65536' out of range for constraint 'j'}}
41   // thumb1-error@37 {{invalid input constraint 'j' in asm}}
42   // thumb2-error@37 {{value '65536' out of range for constraint 'j'}}
43   return res;
44 }
45 
46 // I: An immediate integer valid for a data-processing instruction. (ARM/Thumb2)
47 //    An immediate integer between 0 and 255. (Thumb1)
test_I(int i)48 int test_I(int i) {
49   int res;
50   __asm(
51       "add %0, %1;"
52       : [ result ] "=r"(res)
53       : [ constant ] "I"(-1), [ input ] "r"(i)
54       :); // thumb1-error@53 {{value '-1' out of range for constraint 'I'}}
55   __asm(
56       "add %0, %1;"
57       : [ result ] "=r"(res)
58       : [ constant ] "I"(0), [ input ] "r"(i)
59       :); // No errors expected.
60   __asm(
61       "add %0, %1;"
62       : [ result ] "=r"(res)
63       : [ constant ] "I"(255), [ input ] "r"(i)
64       :); // No errors expected.
65   __asm(
66       "add %0, %1;"
67       : [ result ] "=r"(res)
68       : [ constant ] "I"(256), [ input ] "r"(i)
69       :); // thumb1-error@68 {{value '256' out of range for constraint 'I'}}
70   return res;
71 }
72 
73 // J: An immediate integer between -4095 and 4095. (ARM/Thumb2)
74 //    An immediate integer between -255 and -1. (Thumb1)
test_J(int i)75 int test_J(int i) {
76   int res;
77   __asm(
78       "movw %0, %1;"
79       : [ result ] "=r"(res)
80       : [ constant ] "J"(-4096), [ input ] "r"(i)
81       :);
82   // arm6-error@80 {{value '-4096' out of range for constraint 'J'}}
83   // arm7-error@80 {{value '-4096' out of range for constraint 'J'}}
84   // thumb1-error@80 {{value '-4096' out of range for constraint 'J'}}
85   // thumb2-error@80 {{value '-4096' out of range for constraint 'J'}}
86   __asm(
87       "movw %0, %1;"
88       : [ result ] "=r"(res)
89       : [ constant ] "J"(-4095), [ input ] "r"(i)
90       :);
91   // thumb1-error@89 {{value '-4095' out of range for constraint 'J'}}
92   __asm(
93       "add %0, %1;"
94       : [ result ] "=r"(res)
95       : [ constant ] "J"(-256), [ input ] "r"(i)
96       :);
97   // thumb1-error@95 {{value '-256' out of range for constraint 'J'}}
98   __asm(
99       "add %0, %1;"
100       : [ result ] "=r"(res)
101       : [ constant ] "J"(-255), [ input ] "r"(i)
102       :);
103   // No errors expected.
104   __asm(
105       "add %0, %1;"
106       : [ result ] "=r"(res)
107       : [ constant ] "J"(-1), [ input ] "r"(i)
108       :);
109   // No errors expected.
110   __asm(
111       "add %0, %1;"
112       : [ result ] "=r"(res)
113       : [ constant ] "J"(0), [ input ] "r"(i)
114       :);
115   // thumb1-error@113 {{value '0' out of range for constraint 'J'}}
116   __asm(
117       "movw %0, %1;"
118       : [ result ] "=r"(res)
119       : [ constant ] "J"(4095), [ input ] "r"(i)
120       :);
121   // thumb1-error@119 {{value '4095' out of range for constraint 'J'}}
122   __asm(
123       "movw %0, %1;"
124       : [ result ] "=r"(res)
125       : [ constant ] "J"(4096), [ input ] "r"(i)
126       :);
127   // arm6-error@125 {{value '4096' out of range for constraint 'J'}}
128   // arm7-error@125 {{value '4096' out of range for constraint 'J'}}
129   // thumb1-error@125 {{value '4096' out of range for constraint 'J'}}
130   // thumb2-error@125 {{value '4096' out of range for constraint 'J'}}
131   return res;
132 }
133 
134 // K: An immediate integer whose bitwise inverse is valid for a data-processing instruction. (ARM/Thumb2)
135 //    An immediate integer between 0 and 255, with optional left-shift by some amount. (Thumb1)
test_K(int i)136 int test_K(int i) {
137   int res;
138   __asm(
139       "add %0, %1;"
140       : [ result ] "=r"(res)
141       : [ constant ] "K"(123), [ input ] "r"(i)
142       :);
143   // No errors expected.
144   return res;
145 }
146 
147 // L: An immediate integer whose negation is valid for a data-processing instruction. (ARM/Thumb2)
148 //    An immediate integer between -7 and 7. (Thumb1)
test_L(int i)149 int test_L(int i) {
150   int res;
151   __asm(
152       "add %0, %1;"
153       : [ result ] "=r"(res)
154       : [ constant ] "L"(-8), [ input ] "r"(i)
155       :); // thumb1-error@154 {{value '-8' out of range for constraint 'L'}}
156   __asm(
157       "add %0, %1;"
158       : [ result ] "=r"(res)
159       : [ constant ] "L"(-7), [ input ] "r"(i)
160       :); // No errors expected.
161   __asm(
162       "add %0, %1;"
163       : [ result ] "=r"(res)
164       : [ constant ] "L"(7), [ input ] "r"(i)
165       :); // No errors expected.
166   __asm(
167       "add %0, %1;"
168       : [ result ] "=r"(res)
169       : [ constant ] "L"(8), [ input ] "r"(i)
170       :); // thumb1-error@169 {{value '8' out of range for constraint 'L'}}
171   return res;
172 }
173 
174 // M: A power of two or a integer between 0 and 32. (ARM/Thumb2)
175 //    An immediate integer which is a multiple of 4 between 0 and 1020. (Thumb1)
test_M(int i)176 int test_M(int i) {
177   int res;
178   __asm(
179       "add %0, %1;"
180       : [ result ] "=r"(res)
181       : [ constant ] "M"(123), [ input ] "r"(i)
182       :); // No errors expected.
183   return res;
184 }
185 
186 // N: Invalid (ARM/Thumb2)
187 //    An immediate integer between 0 and 31. (Thumb1)
test_N(int i)188 int test_N(int i) {
189   int res;
190   __asm("add %0, %1;"
191         : [ result ] "=r"(res)
192         : [ constant ] "N"(-1), [ input ] "r"(i)
193         :);
194   // arm6-error@192 {{invalid input constraint 'N' in asm}}
195   // arm7-error@192 {{invalid input constraint 'N' in asm}}
196   // thumb1-error@192 {{value '-1' out of range for constraint 'N'}}
197   // thumb2-error@192 {{invalid input constraint 'N' in asm}}
198   __asm(
199       "add %0, %1;"
200       : [ result ] "=r"(res)
201       : [ constant ] "N"(0), [ input ] "r"(i)
202       :);
203   // arm6-error@201 {{invalid input constraint 'N' in asm}}
204   // arm7-error@201 {{invalid input constraint 'N' in asm}}
205   // thumb1-no-error
206   // thumb2-error@201 {{invalid input constraint 'N' in asm}}
207   __asm(
208       "add %0, %1;"
209       : [ result ] "=r"(res)
210       : [ constant ] "N"(31), [ input ] "r"(i)
211       :);
212   // arm6-error@210 {{invalid input constraint 'N' in asm}}
213   // arm7-error@210 {{invalid input constraint 'N' in asm}}
214   // thumb1-no-error
215   // thumb2-error@210 {{invalid input constraint 'N' in asm}}
216   __asm(
217       "add %0, %1;"
218       : [ result ] "=r"(res)
219       : [ constant ] "N"(32), [ input ] "r"(i)
220       :);
221   // arm6-error@219 {{invalid input constraint 'N' in asm}}
222   // arm7-error@219 {{invalid input constraint 'N' in asm}}
223   // thumb1-error@219 {{value '32' out of range for constraint 'N'}}
224   // thumb2-error@219 {{invalid input constraint 'N' in asm}}
225   return res;
226 }
227 
228 // O: Invalid (ARM/Thumb2)
229 //    An immediate integer which is a multiple of 4 between -508 and 508. (Thumb1)
test_O(int i)230 int test_O(int i) {
231   int res;
232   __asm(
233       "add %0, %1;"
234       : [ result ] "=r"(res)
235       : [ constant ] "O"(1), [ input ] "r"(i)
236       :);
237   // arm6-error@235 {{invalid input constraint 'O' in asm}}
238   // arm7-error@235 {{invalid input constraint 'O' in asm}}
239   // thumb1-no-error
240   // thumb2-error@235 {{invalid input constraint 'O' in asm}}
241   return res;
242 }
243 
244 // l: Same as r (ARM)
245 //    A low 32-bit GPR register (r0-r7). (Thumb1/Thumb2)
test_l(int i)246 int test_l(int i) {
247   int res;
248   __asm(
249       "add %0, %1;"
250       : [ result ] "=l"(res)
251       : [ constant ] "i"(10), [ input ] "l"(i)
252       :); // No errors expected.
253   return res;
254 }
255 
256 // h: Invalid (ARM)
257 //    A high 32-bit GPR register (r8-r15). (Thumb1/Thumb2)
test_h(int i)258 int test_h(int i) {
259   int res;
260   __asm(
261       "add %0, %1;"
262       : [ result ] "=h"(res)
263       : [ constant ] "i"(10), [ input ] "h"(i)
264       :);
265   // arm6-error@262 {{invalid output constraint '=h' in asm}}
266   // arm7-error@262 {{invalid output constraint '=h' in asm}}
267   return res;
268 }
269 
270 // s: An integer constant, but allowing only relocatable values.
271 int g;
272 
test_s(int i)273 int test_s(int i) {
274   int res;
275   __asm(
276       "add %0, %1;"
277       : [ result ] "=r"(res)
278       : [ constant ] "s"(&g), [ input ] "r"(i)
279       :); // No errors expected.
280   return res;
281 }
282 
283 // w: A 32, 64, or 128-bit floating-point/SIMD register: s0-s31, d0-d31, or q0-q15.
test_w(float x)284 float test_w(float x) {
285   __asm__("vsqrt.f32 %0, %1"
286           : "=w"(x)
287           : "w"(x)); // No error expected.
288   return x;
289 }
290 
291 // x: A 32, 64, or 128-bit floating-point/SIMD register: s0-s15, d0-d7, or q0-q3.
test_x(float x)292 float test_x(float x) {
293   __asm__("vsqrt.f32 %0, %1"
294           : "=x"(x)
295           : "x"(x)); // No error expected.
296   return x;
297 }
298 
299 // t: A 32, 64, or 128-bit floating-point/SIMD register: s0-s31, d0-d15, or q0-q7.
test_t(float x)300 float test_t(float x) {
301   __asm__("vsqrt.f32 %0, %1"
302           : "=t"(x)
303           : "t"(x)); // No error expected.
304   return x;
305 }
306