1 // RUN: %clang_cc1 -ffreestanding -triple armv8-eabi -target-cpu cortex-a57 -O -S -emit-llvm -o - %s | FileCheck %s -check-prefix=ARM -check-prefix=AArch32 2 // RUN: %clang_cc1 -ffreestanding -triple aarch64-eabi -target-cpu cortex-a57 -target-feature +neon -target-feature +crc -target-feature +crypto -O -S -emit-llvm -o - %s | FileCheck %s -check-prefix=ARM -check-prefix=AArch64 3 4 #include <arm_acle.h> 5 6 /* 8 SYNCHRONIZATION, BARRIER AND HINT INTRINSICS */ 7 /* 8.3 Memory Barriers */ 8 // ARM-LABEL: test_dmb 9 // AArch32: call void @llvm.arm.dmb(i32 1) 10 // AArch64: call void @llvm.aarch64.dmb(i32 1) 11 void test_dmb(void) { 12 __dmb(1); 13 } 14 15 // ARM-LABEL: test_dsb 16 // AArch32: call void @llvm.arm.dsb(i32 2) 17 // AArch64: call void @llvm.aarch64.dsb(i32 2) 18 void test_dsb(void) { 19 __dsb(2); 20 } 21 22 // ARM-LABEL: test_isb 23 // AArch32: call void @llvm.arm.isb(i32 3) 24 // AArch64: call void @llvm.aarch64.isb(i32 3) 25 void test_isb(void) { 26 __isb(3); 27 } 28 29 /* 8.4 Hints */ 30 // ARM-LABEL: test_yield 31 // AArch32: call void @llvm.arm.hint(i32 1) 32 // AArch64: call void @llvm.aarch64.hint(i32 1) 33 void test_yield(void) { 34 __yield(); 35 } 36 37 // ARM-LABEL: test_wfe 38 // AArch32: call void @llvm.arm.hint(i32 2) 39 // AArch64: call void @llvm.aarch64.hint(i32 2) 40 void test_wfe(void) { 41 __wfe(); 42 } 43 44 // ARM-LABEL: test_wfi 45 // AArch32: call void @llvm.arm.hint(i32 3) 46 // AArch64: call void @llvm.aarch64.hint(i32 3) 47 void test_wfi(void) { 48 __wfi(); 49 } 50 51 // ARM-LABEL: test_sev 52 // AArch32: call void @llvm.arm.hint(i32 4) 53 // AArch64: call void @llvm.aarch64.hint(i32 4) 54 void test_sev(void) { 55 __sev(); 56 } 57 58 // ARM-LABEL: test_sevl 59 // AArch32: call void @llvm.arm.hint(i32 5) 60 // AArch64: call void @llvm.aarch64.hint(i32 5) 61 void test_sevl(void) { 62 __sevl(); 63 } 64 65 #if __ARM_32BIT_STATE 66 // AArch32-LABEL: test_dbg 67 // AArch32: call void @llvm.arm.dbg(i32 0) 68 void test_dbg(void) { 69 __dbg(0); 70 } 71 #endif 72 73 /* 8.5 Swap */ 74 // ARM-LABEL: test_swp 75 // AArch32: call i32 @llvm.arm.ldrex 76 // AArch32: call i32 @llvm.arm.strex 77 // AArch64: call i64 @llvm.aarch64.ldxr 78 // AArch64: call i32 @llvm.aarch64.stxr 79 void test_swp(uint32_t x, volatile void *p) { 80 __swp(x, p); 81 } 82 83 /* 8.6 Memory prefetch intrinsics */ 84 /* 8.6.1 Data prefetch */ 85 // ARM-LABEL: test_pld 86 // ARM: call void @llvm.prefetch(i8* null, i32 0, i32 3, i32 1) 87 void test_pld() { 88 __pld(0); 89 } 90 91 // ARM-LABEL: test_pldx 92 // AArch32: call void @llvm.prefetch(i8* null, i32 1, i32 3, i32 1) 93 // AArch64: call void @llvm.prefetch(i8* null, i32 1, i32 1, i32 1) 94 void test_pldx() { 95 __pldx(1, 2, 0, 0); 96 } 97 98 /* 8.6.2 Instruction prefetch */ 99 // ARM-LABEL: test_pli 100 // ARM: call void @llvm.prefetch(i8* null, i32 0, i32 3, i32 0) 101 void test_pli() { 102 __pli(0); 103 } 104 105 // ARM-LABEL: test_plix 106 // AArch32: call void @llvm.prefetch(i8* null, i32 0, i32 3, i32 0) 107 // AArch64: call void @llvm.prefetch(i8* null, i32 0, i32 1, i32 0) 108 void test_plix() { 109 __plix(2, 0, 0); 110 } 111 112 /* 8.7 NOP */ 113 // ARM-LABEL: test_nop 114 // AArch32: call void @llvm.arm.hint(i32 0) 115 // AArch64: call void @llvm.aarch64.hint(i32 0) 116 void test_nop(void) { 117 __nop(); 118 } 119 120 /* 9 DATA-PROCESSING INTRINSICS */ 121 122 /* 9.2 Miscellaneous data-processing intrinsics */ 123 // ARM-LABEL: test_ror 124 // ARM: lshr 125 // ARM: sub 126 // ARM: shl 127 // ARM: or 128 uint32_t test_ror(uint32_t x, uint32_t y) { 129 return __ror(x, y); 130 } 131 132 // ARM-LABEL: test_rorl 133 // ARM: lshr 134 // ARM: sub 135 // ARM: shl 136 // ARM: or 137 unsigned long test_rorl(unsigned long x, uint32_t y) { 138 return __rorl(x, y); 139 } 140 141 // ARM-LABEL: test_rorll 142 // ARM: lshr 143 // ARM: sub 144 // ARM: shl 145 // ARM: or 146 uint64_t test_rorll(uint64_t x, uint32_t y) { 147 return __rorll(x, y); 148 } 149 150 // ARM-LABEL: test_clz 151 // ARM: call i32 @llvm.ctlz.i32(i32 %t, i1 false) 152 uint32_t test_clz(uint32_t t) { 153 return __clz(t); 154 } 155 156 // ARM-LABEL: test_clzl 157 // AArch32: call i32 @llvm.ctlz.i32(i32 %t, i1 false) 158 // AArch64: call i64 @llvm.ctlz.i64(i64 %t, i1 false) 159 long test_clzl(long t) { 160 return __clzl(t); 161 } 162 163 // ARM-LABEL: test_clzll 164 // ARM: call i64 @llvm.ctlz.i64(i64 %t, i1 false) 165 uint64_t test_clzll(uint64_t t) { 166 return __clzll(t); 167 } 168 169 // ARM-LABEL: test_rev 170 // ARM: call i32 @llvm.bswap.i32(i32 %t) 171 uint32_t test_rev(uint32_t t) { 172 return __rev(t); 173 } 174 175 // ARM-LABEL: test_revl 176 // AArch32: call i32 @llvm.bswap.i32(i32 %t) 177 // AArch64: call i64 @llvm.bswap.i64(i64 %t) 178 long test_revl(long t) { 179 return __revl(t); 180 } 181 182 // ARM-LABEL: test_revll 183 // ARM: call i64 @llvm.bswap.i64(i64 %t) 184 uint64_t test_revll(uint64_t t) { 185 return __revll(t); 186 } 187 188 // ARM-LABEL: test_rev16 189 // ARM: llvm.bswap 190 // ARM: lshr {{.*}}, 16 191 // ARM: shl {{.*}}, 16 192 // ARM: or 193 uint32_t test_rev16(uint32_t t) { 194 return __rev16(t); 195 } 196 197 // ARM-LABEL: test_rev16l 198 // AArch32: llvm.bswap 199 // AArch32: lshr {{.*}}, 16 200 // AArch32: shl {{.*}}, 16 201 // AArch32: or 202 // AArch64: [[T1:%.*]] = lshr i64 [[IN:%.*]], 32 203 // AArch64: [[T2:%.*]] = trunc i64 [[T1]] to i32 204 // AArch64: [[T3:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T2]]) 205 // AArch64: [[T4:%.*]] = lshr i32 [[T3]], 16 206 // AArch64: [[T5:%.*]] = shl i32 [[T3]], 16 207 // AArch64: [[T6:%.*]] = or i32 [[T5]], [[T4]] 208 // AArch64: [[T7:%.*]] = zext i32 [[T6]] to i64 209 // AArch64: [[T8:%.*]] = shl nuw i64 [[T7]], 32 210 // AArch64: [[T9:%.*]] = trunc i64 [[IN]] to i32 211 // AArch64: [[T10:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T9]]) 212 // AArch64: [[T11:%.*]] = lshr i32 [[T10]], 16 213 // AArch64: [[T12:%.*]] = shl i32 [[T10]], 16 214 // AArch64: [[T13:%.*]] = or i32 [[T12]], [[T11]] 215 // AArch64: [[T14:%.*]] = zext i32 [[T13]] to i64 216 // AArch64: [[T15:%.*]] = or i64 [[T8]], [[T14]] 217 long test_rev16l(long t) { 218 return __rev16l(t); 219 } 220 221 // ARM-LABEL: test_rev16ll 222 // ARM: [[T1:%.*]] = lshr i64 [[IN:%.*]], 32 223 // ARM: [[T2:%.*]] = trunc i64 [[T1]] to i32 224 // ARM: [[T3:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T2]]) 225 // ARM: [[T4:%.*]] = lshr i32 [[T3]], 16 226 // ARM: [[T5:%.*]] = shl i32 [[T3]], 16 227 // ARM: [[T6:%.*]] = or i32 [[T5]], [[T4]] 228 // ARM: [[T7:%.*]] = zext i32 [[T6]] to i64 229 // ARM: [[T8:%.*]] = shl nuw i64 [[T7]], 32 230 // ARM: [[T9:%.*]] = trunc i64 [[IN]] to i32 231 // ARM: [[T10:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T9]]) 232 // ARM: [[T11:%.*]] = lshr i32 [[T10]], 16 233 // ARM: [[T12:%.*]] = shl i32 [[T10]], 16 234 // ARM: [[T13:%.*]] = or i32 [[T12]], [[T11]] 235 // ARM: [[T14:%.*]] = zext i32 [[T13]] to i64 236 // ARM: [[T15:%.*]] = or i64 [[T8]], [[T14]] 237 uint64_t test_rev16ll(uint64_t t) { 238 return __rev16ll(t); 239 } 240 241 // ARM-LABEL: test_revsh 242 // ARM: call i16 @llvm.bswap.i16(i16 %t) 243 int16_t test_revsh(int16_t t) { 244 return __revsh(t); 245 } 246 247 // ARM-LABEL: test_rbit 248 // AArch32: call i32 @llvm.bitreverse.i32 249 // AArch64: call i32 @llvm.bitreverse.i32 250 uint32_t test_rbit(uint32_t t) { 251 return __rbit(t); 252 } 253 254 // ARM-LABEL: test_rbitl 255 // AArch32: call i32 @llvm.bitreverse.i32 256 // AArch64: call i64 @llvm.bitreverse.i64 257 long test_rbitl(long t) { 258 return __rbitl(t); 259 } 260 261 // ARM-LABEL: test_rbitll 262 // AArch32: call i32 @llvm.bitreverse.i32 263 // AArch32: call i32 @llvm.bitreverse.i32 264 // AArch64: call i64 @llvm.bitreverse.i64 265 uint64_t test_rbitll(uint64_t t) { 266 return __rbitll(t); 267 } 268 269 /* 9.4 Saturating intrinsics */ 270 #ifdef __ARM_FEATURE_SAT 271 /* 9.4.1 Width-specified saturation intrinsics */ 272 // AArch32-LABEL: test_ssat 273 // AArch32: call i32 @llvm.arm.ssat(i32 %t, i32 1) 274 int32_t test_ssat(int32_t t) { 275 return __ssat(t, 1); 276 } 277 278 // AArch32-LABEL: test_usat 279 // AArch32: call i32 @llvm.arm.usat(i32 %t, i32 2) 280 uint32_t test_usat(int32_t t) { 281 return __usat(t, 2); 282 } 283 #endif 284 285 /* 9.4.2 Saturating addition and subtraction intrinsics */ 286 #ifdef __ARM_FEATURE_DSP 287 // AArch32-LABEL: test_qadd 288 // AArch32: call i32 @llvm.arm.qadd(i32 %a, i32 %b) 289 int32_t test_qadd(int32_t a, int32_t b) { 290 return __qadd(a, b); 291 } 292 293 // AArch32-LABEL: test_qsub 294 // AArch32: call i32 @llvm.arm.qsub(i32 %a, i32 %b) 295 int32_t test_qsub(int32_t a, int32_t b) { 296 return __qsub(a, b); 297 } 298 299 extern int32_t f(); 300 // AArch32-LABEL: test_qdbl 301 // AArch32: [[VAR:%[a-z0-9]+]] = {{.*}} call {{.*}} @f 302 // AArch32-NOT: call {{.*}} @f 303 // AArch32: call i32 @llvm.arm.qadd(i32 [[VAR]], i32 [[VAR]]) 304 int32_t test_qdbl() { 305 return __qdbl(f()); 306 } 307 #endif 308 309 /* 310 * 9.3 16-bit multiplications 311 */ 312 #if __ARM_FEATURE_DSP 313 // AArch32-LABEL: test_smulbb 314 // AArch32: call i32 @llvm.arm.smulbb 315 int32_t test_smulbb(int32_t a, int32_t b) { 316 return __smulbb(a, b); 317 } 318 // AArch32-LABEL: test_smulbt 319 // AArch32: call i32 @llvm.arm.smulbt 320 int32_t test_smulbt(int32_t a, int32_t b) { 321 return __smulbt(a, b); 322 } 323 // AArch32-LABEL: test_smultb 324 // AArch32: call i32 @llvm.arm.smultb 325 int32_t test_smultb(int32_t a, int32_t b) { 326 return __smultb(a, b); 327 } 328 // AArch32-LABEL: test_smultt 329 // AArch32: call i32 @llvm.arm.smultt 330 int32_t test_smultt(int32_t a, int32_t b) { 331 return __smultt(a, b); 332 } 333 // AArch32-LABEL: test_smulwb 334 // AArch32: call i32 @llvm.arm.smulwb 335 int32_t test_smulwb(int32_t a, int32_t b) { 336 return __smulwb(a, b); 337 } 338 // AArch32-LABEL: test_smulwt 339 // AArch32: call i32 @llvm.arm.smulwt 340 int32_t test_smulwt(int32_t a, int32_t b) { 341 return __smulwt(a, b); 342 } 343 #endif 344 345 /* 9.4.3 Accumultating multiplications */ 346 #if __ARM_FEATURE_DSP 347 // AArch32-LABEL: test_smlabb 348 // AArch32: call i32 @llvm.arm.smlabb(i32 %a, i32 %b, i32 %c) 349 int32_t test_smlabb(int32_t a, int32_t b, int32_t c) { 350 return __smlabb(a, b, c); 351 } 352 // AArch32-LABEL: test_smlabt 353 // AArch32: call i32 @llvm.arm.smlabt(i32 %a, i32 %b, i32 %c) 354 int32_t test_smlabt(int32_t a, int32_t b, int32_t c) { 355 return __smlabt(a, b, c); 356 } 357 // AArch32-LABEL: test_smlatb 358 // AArch32: call i32 @llvm.arm.smlatb(i32 %a, i32 %b, i32 %c) 359 int32_t test_smlatb(int32_t a, int32_t b, int32_t c) { 360 return __smlatb(a, b, c); 361 } 362 // AArch32-LABEL: test_smlatt 363 // AArch32: call i32 @llvm.arm.smlatt(i32 %a, i32 %b, i32 %c) 364 int32_t test_smlatt(int32_t a, int32_t b, int32_t c) { 365 return __smlatt(a, b, c); 366 } 367 // AArch32-LABEL: test_smlawb 368 // AArch32: call i32 @llvm.arm.smlawb(i32 %a, i32 %b, i32 %c) 369 int32_t test_smlawb(int32_t a, int32_t b, int32_t c) { 370 return __smlawb(a, b, c); 371 } 372 // AArch32-LABEL: test_smlawt 373 // AArch32: call i32 @llvm.arm.smlawt(i32 %a, i32 %b, i32 %c) 374 int32_t test_smlawt(int32_t a, int32_t b, int32_t c) { 375 return __smlawt(a, b, c); 376 } 377 #endif 378 379 /* 9.5.4 Parallel 16-bit saturation */ 380 #if __ARM_FEATURE_SIMD32 381 // AArch32-LABEL: test_ssat16 382 // AArch32: call i32 @llvm.arm.ssat16 383 int16x2_t test_ssat16(int16x2_t a) { 384 return __ssat16(a, 15); 385 } 386 // AArch32-LABEL: test_usat16 387 // AArch32: call i32 @llvm.arm.usat16 388 uint16x2_t test_usat16(int16x2_t a) { 389 return __usat16(a, 15); 390 } 391 #endif 392 393 /* 9.5.5 Packing and unpacking */ 394 #if __ARM_FEATURE_SIMD32 395 // AArch32-LABEL: test_sxtab16 396 // AArch32: call i32 @llvm.arm.sxtab16 397 int16x2_t test_sxtab16(int16x2_t a, int8x4_t b) { 398 return __sxtab16(a, b); 399 } 400 // AArch32-LABEL: test_sxtb16 401 // AArch32: call i32 @llvm.arm.sxtb16 402 int16x2_t test_sxtb16(int8x4_t a) { 403 return __sxtb16(a); 404 } 405 // AArch32-LABEL: test_uxtab16 406 // AArch32: call i32 @llvm.arm.uxtab16 407 int16x2_t test_uxtab16(int16x2_t a, int8x4_t b) { 408 return __uxtab16(a, b); 409 } 410 // AArch32-LABEL: test_uxtb16 411 // AArch32: call i32 @llvm.arm.uxtb16 412 int16x2_t test_uxtb16(int8x4_t a) { 413 return __uxtb16(a); 414 } 415 #endif 416 417 /* 9.5.6 Parallel selection */ 418 #if __ARM_FEATURE_SIMD32 419 // AArch32-LABEL: test_sel 420 // AArch32: call i32 @llvm.arm.sel 421 uint8x4_t test_sel(uint8x4_t a, uint8x4_t b) { 422 return __sel(a, b); 423 } 424 #endif 425 426 /* 9.5.7 Parallel 8-bit addition and subtraction */ 427 #if __ARM_FEATURE_SIMD32 428 // AArch32-LABEL: test_qadd8 429 // AArch32: call i32 @llvm.arm.qadd8 430 int16x2_t test_qadd8(int8x4_t a, int8x4_t b) { 431 return __qadd8(a, b); 432 } 433 // AArch32-LABEL: test_qsub8 434 // AArch32: call i32 @llvm.arm.qsub8 435 int8x4_t test_qsub8(int8x4_t a, int8x4_t b) { 436 return __qsub8(a, b); 437 } 438 // AArch32-LABEL: test_sadd8 439 // AArch32: call i32 @llvm.arm.sadd8 440 int8x4_t test_sadd8(int8x4_t a, int8x4_t b) { 441 return __sadd8(a, b); 442 } 443 // AArch32-LABEL: test_shadd8 444 // AArch32: call i32 @llvm.arm.shadd8 445 int8x4_t test_shadd8(int8x4_t a, int8x4_t b) { 446 return __shadd8(a, b); 447 } 448 // AArch32-LABEL: test_shsub8 449 // AArch32: call i32 @llvm.arm.shsub8 450 int8x4_t test_shsub8(int8x4_t a, int8x4_t b) { 451 return __shsub8(a, b); 452 } 453 // AArch32-LABEL: test_ssub8 454 // AArch32: call i32 @llvm.arm.ssub8 455 int8x4_t test_ssub8(int8x4_t a, int8x4_t b) { 456 return __ssub8(a, b); 457 } 458 // AArch32-LABEL: test_uadd8 459 // AArch32: call i32 @llvm.arm.uadd8 460 uint8x4_t test_uadd8(uint8x4_t a, uint8x4_t b) { 461 return __uadd8(a, b); 462 } 463 // AArch32-LABEL: test_uhadd8 464 // AArch32: call i32 @llvm.arm.uhadd8 465 uint8x4_t test_uhadd8(uint8x4_t a, uint8x4_t b) { 466 return __uhadd8(a, b); 467 } 468 // AArch32-LABEL: test_uhsub8 469 // AArch32: call i32 @llvm.arm.uhsub8 470 uint8x4_t test_uhsub8(uint8x4_t a, uint8x4_t b) { 471 return __uhsub8(a, b); 472 } 473 // AArch32-LABEL: test_uqadd8 474 // AArch32: call i32 @llvm.arm.uqadd8 475 uint8x4_t test_uqadd8(uint8x4_t a, uint8x4_t b) { 476 return __uqadd8(a, b); 477 } 478 // AArch32-LABEL: test_uqsub8 479 // AArch32: call i32 @llvm.arm.uqsub8 480 uint8x4_t test_uqsub8(uint8x4_t a, uint8x4_t b) { 481 return __uqsub8(a, b); 482 } 483 // AArch32-LABEL: test_usub8 484 // AArch32: call i32 @llvm.arm.usub8 485 uint8x4_t test_usub8(uint8x4_t a, uint8x4_t b) { 486 return __usub8(a, b); 487 } 488 #endif 489 490 /* 9.5.8 Sum of 8-bit absolute differences */ 491 #if __ARM_FEATURE_SIMD32 492 // AArch32-LABEL: test_usad8 493 // AArch32: call i32 @llvm.arm.usad8 494 uint32_t test_usad8(uint8x4_t a, uint8x4_t b) { 495 return __usad8(a, b); 496 } 497 // AArch32-LABEL: test_usada8 498 // AArch32: call i32 @llvm.arm.usada8 499 uint32_t test_usada8(uint8_t a, uint8_t b, uint8_t c) { 500 return __usada8(a, b, c); 501 } 502 #endif 503 504 /* 9.5.9 Parallel 16-bit addition and subtraction */ 505 #if __ARM_FEATURE_SIMD32 506 // AArch32-LABEL: test_qadd16 507 // AArch32: call i32 @llvm.arm.qadd16 508 int16x2_t test_qadd16(int16x2_t a, int16x2_t b) { 509 return __qadd16(a, b); 510 } 511 // AArch32-LABEL: test_qasx 512 // AArch32: call i32 @llvm.arm.qasx 513 int16x2_t test_qasx(int16x2_t a, int16x2_t b) { 514 return __qasx(a, b); 515 } 516 // AArch32-LABEL: test_qsax 517 // AArch32: call i32 @llvm.arm.qsax 518 int16x2_t test_qsax(int16x2_t a, int16x2_t b) { 519 return __qsax(a, b); 520 } 521 // AArch32-LABEL: test_qsub16 522 // AArch32: call i32 @llvm.arm.qsub16 523 int16x2_t test_qsub16(int16x2_t a, int16x2_t b) { 524 return __qsub16(a, b); 525 } 526 // AArch32-LABEL: test_sadd16 527 // AArch32: call i32 @llvm.arm.sadd16 528 int16x2_t test_sadd16(int16x2_t a, int16x2_t b) { 529 return __sadd16(a, b); 530 } 531 // AArch32-LABEL: test_sasx 532 // AArch32: call i32 @llvm.arm.sasx 533 int16x2_t test_sasx(int16x2_t a, int16x2_t b) { 534 return __sasx(a, b); 535 } 536 // AArch32-LABEL: test_shadd16 537 // AArch32: call i32 @llvm.arm.shadd16 538 int16x2_t test_shadd16(int16x2_t a, int16x2_t b) { 539 return __shadd16(a, b); 540 } 541 // AArch32-LABEL: test_shasx 542 // AArch32: call i32 @llvm.arm.shasx 543 int16x2_t test_shasx(int16x2_t a, int16x2_t b) { 544 return __shasx(a, b); 545 } 546 // AArch32-LABEL: test_shsax 547 // AArch32: call i32 @llvm.arm.shsax 548 int16x2_t test_shsax(int16x2_t a, int16x2_t b) { 549 return __shsax(a, b); 550 } 551 // AArch32-LABEL: test_shsub16 552 // AArch32: call i32 @llvm.arm.shsub16 553 int16x2_t test_shsub16(int16x2_t a, int16x2_t b) { 554 return __shsub16(a, b); 555 } 556 // AArch32-LABEL: test_ssax 557 // AArch32: call i32 @llvm.arm.ssax 558 int16x2_t test_ssax(int16x2_t a, int16x2_t b) { 559 return __ssax(a, b); 560 } 561 // AArch32-LABEL: test_ssub16 562 // AArch32: call i32 @llvm.arm.ssub16 563 int16x2_t test_ssub16(int16x2_t a, int16x2_t b) { 564 return __ssub16(a, b); 565 } 566 // AArch32-LABEL: test_uadd16 567 // AArch32: call i32 @llvm.arm.uadd16 568 uint16x2_t test_uadd16(uint16x2_t a, uint16x2_t b) { 569 return __uadd16(a, b); 570 } 571 // AArch32-LABEL: test_uasx 572 // AArch32: call i32 @llvm.arm.uasx 573 uint16x2_t test_uasx(uint16x2_t a, uint16x2_t b) { 574 return __uasx(a, b); 575 } 576 // AArch32-LABEL: test_uhadd16 577 // AArch32: call i32 @llvm.arm.uhadd16 578 uint16x2_t test_uhadd16(uint16x2_t a, uint16x2_t b) { 579 return __uhadd16(a, b); 580 } 581 // AArch32-LABEL: test_uhasx 582 // AArch32: call i32 @llvm.arm.uhasx 583 uint16x2_t test_uhasx(uint16x2_t a, uint16x2_t b) { 584 return __uhasx(a, b); 585 } 586 // AArch32-LABEL: test_uhsax 587 // AArch32: call i32 @llvm.arm.uhsax 588 uint16x2_t test_uhsax(uint16x2_t a, uint16x2_t b) { 589 return __uhsax(a, b); 590 } 591 // AArch32-LABEL: test_uhsub16 592 // AArch32: call i32 @llvm.arm.uhsub16 593 uint16x2_t test_uhsub16(uint16x2_t a, uint16x2_t b) { 594 return __uhsub16(a, b); 595 } 596 // AArch32-LABEL: test_uqadd16 597 // AArch32: call i32 @llvm.arm.uqadd16 598 uint16x2_t test_uqadd16(uint16x2_t a, uint16x2_t b) { 599 return __uqadd16(a, b); 600 } 601 // AArch32-LABEL: test_uqasx 602 // AArch32: call i32 @llvm.arm.uqasx 603 uint16x2_t test_uqasx(uint16x2_t a, uint16x2_t b) { 604 return __uqasx(a, b); 605 } 606 // AArch32-LABEL: test_uqsax 607 // AArch32: call i32 @llvm.arm.uqsax 608 uint16x2_t test_uqsax(uint16x2_t a, uint16x2_t b) { 609 return __uqsax(a, b); 610 } 611 // AArch32-LABEL: test_uqsub16 612 // AArch32: call i32 @llvm.arm.uqsub16 613 uint16x2_t test_uqsub16(uint16x2_t a, uint16x2_t b) { 614 return __uqsub16(a, b); 615 } 616 // AArch32-LABEL: test_usax 617 // AArch32: call i32 @llvm.arm.usax 618 uint16x2_t test_usax(uint16x2_t a, uint16x2_t b) { 619 return __usax(a, b); 620 } 621 // AArch32-LABEL: test_usub16 622 // AArch32: call i32 @llvm.arm.usub16 623 uint16x2_t test_usub16(uint16x2_t a, uint16x2_t b) { 624 return __usub16(a, b); 625 } 626 #endif 627 628 /* 9.5.10 Parallel 16-bit multiplications */ 629 #if __ARM_FEATURE_SIMD32 630 // AArch32-LABEL: test_smlad 631 // AArch32: call i32 @llvm.arm.smlad 632 int32_t test_smlad(int16x2_t a, int16x2_t b, int32_t c) { 633 return __smlad(a, b, c); 634 } 635 // AArch32-LABEL: test_smladx 636 // AArch32: call i32 @llvm.arm.smladx 637 int32_t test_smladx(int16x2_t a, int16x2_t b, int32_t c) { 638 return __smladx(a, b, c); 639 } 640 // AArch32-LABEL: test_smlald 641 // AArch32: call i64 @llvm.arm.smlald 642 int64_t test_smlald(int16x2_t a, int16x2_t b, int64_t c) { 643 return __smlald(a, b, c); 644 } 645 // AArch32-LABEL: test_smlaldx 646 // AArch32: call i64 @llvm.arm.smlaldx 647 int64_t test_smlaldx(int16x2_t a, int16x2_t b, int64_t c) { 648 return __smlaldx(a, b, c); 649 } 650 // AArch32-LABEL: test_smlsd 651 // AArch32: call i32 @llvm.arm.smlsd 652 int32_t test_smlsd(int16x2_t a, int16x2_t b, int32_t c) { 653 return __smlsd(a, b, c); 654 } 655 // AArch32-LABEL: test_smlsdx 656 // AArch32: call i32 @llvm.arm.smlsdx 657 int32_t test_smlsdx(int16x2_t a, int16x2_t b, int32_t c) { 658 return __smlsdx(a, b, c); 659 } 660 // AArch32-LABEL: test_smlsld 661 // AArch32: call i64 @llvm.arm.smlsld 662 int64_t test_smlsld(int16x2_t a, int16x2_t b, int64_t c) { 663 return __smlsld(a, b, c); 664 } 665 // AArch32-LABEL: test_smlsldx 666 // AArch32: call i64 @llvm.arm.smlsldx 667 int64_t test_smlsldx(int16x2_t a, int16x2_t b, int64_t c) { 668 return __smlsldx(a, b, c); 669 } 670 // AArch32-LABEL: test_smuad 671 // AArch32: call i32 @llvm.arm.smuad 672 int32_t test_smuad(int16x2_t a, int16x2_t b) { 673 return __smuad(a, b); 674 } 675 // AArch32-LABEL: test_smuadx 676 // AArch32: call i32 @llvm.arm.smuadx 677 int32_t test_smuadx(int16x2_t a, int16x2_t b) { 678 return __smuadx(a, b); 679 } 680 // AArch32-LABEL: test_smusd 681 // AArch32: call i32 @llvm.arm.smusd 682 int32_t test_smusd(int16x2_t a, int16x2_t b) { 683 return __smusd(a, b); 684 } 685 // AArch32-LABEL: test_smusdx 686 // AArch32: call i32 @llvm.arm.smusdx 687 int32_t test_smusdx(int16x2_t a, int16x2_t b) { 688 return __smusdx(a, b); 689 } 690 #endif 691 692 /* 9.7 CRC32 intrinsics */ 693 // ARM-LABEL: test_crc32b 694 // AArch32: call i32 @llvm.arm.crc32b 695 // AArch64: call i32 @llvm.aarch64.crc32b 696 uint32_t test_crc32b(uint32_t a, uint8_t b) { 697 return __crc32b(a, b); 698 } 699 700 // ARM-LABEL: test_crc32h 701 // AArch32: call i32 @llvm.arm.crc32h 702 // AArch64: call i32 @llvm.aarch64.crc32h 703 uint32_t test_crc32h(uint32_t a, uint16_t b) { 704 return __crc32h(a, b); 705 } 706 707 // ARM-LABEL: test_crc32w 708 // AArch32: call i32 @llvm.arm.crc32w 709 // AArch64: call i32 @llvm.aarch64.crc32w 710 uint32_t test_crc32w(uint32_t a, uint32_t b) { 711 return __crc32w(a, b); 712 } 713 714 // ARM-LABEL: test_crc32d 715 // AArch32: call i32 @llvm.arm.crc32w 716 // AArch32: call i32 @llvm.arm.crc32w 717 // AArch64: call i32 @llvm.aarch64.crc32x 718 uint32_t test_crc32d(uint32_t a, uint64_t b) { 719 return __crc32d(a, b); 720 } 721 722 // ARM-LABEL: test_crc32cb 723 // AArch32: call i32 @llvm.arm.crc32cb 724 // AArch64: call i32 @llvm.aarch64.crc32cb 725 uint32_t test_crc32cb(uint32_t a, uint8_t b) { 726 return __crc32cb(a, b); 727 } 728 729 // ARM-LABEL: test_crc32ch 730 // AArch32: call i32 @llvm.arm.crc32ch 731 // AArch64: call i32 @llvm.aarch64.crc32ch 732 uint32_t test_crc32ch(uint32_t a, uint16_t b) { 733 return __crc32ch(a, b); 734 } 735 736 // ARM-LABEL: test_crc32cw 737 // AArch32: call i32 @llvm.arm.crc32cw 738 // AArch64: call i32 @llvm.aarch64.crc32cw 739 uint32_t test_crc32cw(uint32_t a, uint32_t b) { 740 return __crc32cw(a, b); 741 } 742 743 // ARM-LABEL: test_crc32cd 744 // AArch32: call i32 @llvm.arm.crc32cw 745 // AArch32: call i32 @llvm.arm.crc32cw 746 // AArch64: call i32 @llvm.aarch64.crc32cx 747 uint32_t test_crc32cd(uint32_t a, uint64_t b) { 748 return __crc32cd(a, b); 749 } 750 751 /* 10.1 Special register intrinsics */ 752 // ARM-LABEL: test_rsr 753 // AArch64: call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]]) 754 // AArch32: call i32 @llvm.read_register.i32(metadata ![[M2:[0-9]]]) 755 uint32_t test_rsr() { 756 #ifdef __ARM_32BIT_STATE 757 return __arm_rsr("cp1:2:c3:c4:5"); 758 #else 759 return __arm_rsr("1:2:3:4:5"); 760 #endif 761 } 762 763 // ARM-LABEL: test_rsr64 764 // AArch64: call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]]) 765 // AArch32: call i64 @llvm.read_register.i64(metadata ![[M3:[0-9]]]) 766 uint64_t test_rsr64() { 767 #ifdef __ARM_32BIT_STATE 768 return __arm_rsr64("cp1:2:c3"); 769 #else 770 return __arm_rsr64("1:2:3:4:5"); 771 #endif 772 } 773 774 // ARM-LABEL: test_rsrp 775 // AArch64: call i64 @llvm.read_register.i64(metadata ![[M1:[0-9]]]) 776 // AArch32: call i32 @llvm.read_register.i32(metadata ![[M4:[0-9]]]) 777 void *test_rsrp() { 778 return __arm_rsrp("sysreg"); 779 } 780 781 // ARM-LABEL: test_wsr 782 // AArch64: call void @llvm.write_register.i64(metadata ![[M0:[0-9]]], i64 %{{.*}}) 783 // AArch32: call void @llvm.write_register.i32(metadata ![[M2:[0-9]]], i32 %{{.*}}) 784 void test_wsr(uint32_t v) { 785 #ifdef __ARM_32BIT_STATE 786 __arm_wsr("cp1:2:c3:c4:5", v); 787 #else 788 __arm_wsr("1:2:3:4:5", v); 789 #endif 790 } 791 792 // ARM-LABEL: test_wsr64 793 // AArch64: call void @llvm.write_register.i64(metadata ![[M0:[0-9]]], i64 %{{.*}}) 794 // AArch32: call void @llvm.write_register.i64(metadata ![[M3:[0-9]]], i64 %{{.*}}) 795 void test_wsr64(uint64_t v) { 796 #ifdef __ARM_32BIT_STATE 797 __arm_wsr64("cp1:2:c3", v); 798 #else 799 __arm_wsr64("1:2:3:4:5", v); 800 #endif 801 } 802 803 // ARM-LABEL: test_wsrp 804 // AArch64: call void @llvm.write_register.i64(metadata ![[M1:[0-9]]], i64 %{{.*}}) 805 // AArch32: call void @llvm.write_register.i32(metadata ![[M4:[0-9]]], i32 %{{.*}}) 806 void test_wsrp(void *v) { 807 __arm_wsrp("sysreg", v); 808 } 809 810 // AArch32: ![[M2]] = !{!"cp1:2:c3:c4:5"} 811 // AArch32: ![[M3]] = !{!"cp1:2:c3"} 812 // AArch32: ![[M4]] = !{!"sysreg"} 813 814 // AArch64: ![[M0]] = !{!"1:2:3:4:5"} 815 // AArch64: ![[M1]] = !{!"sysreg"} 816