1 // RUN: %clang_cc1 -triple riscv32 -O2 -emit-llvm %s -o - \
3 // RUN: %clang_cc1 -triple riscv64 -O2 -emit-llvm %s -o - \
6 // Test RISC-V specific inline assembly constraints and modifiers.
9 // CHECK-LABEL: define{{.*}} {{i64|i32}} @test_r(
10 // CHECK: call {{i64|i32}} asm sideeffect "", "=r,r"({{i64|i32}} %{{.*}})
12 asm volatile ("" : "=r"(ret
) : "r"(x
));
13 // CHECK: call {{i64|i32}} asm sideeffect "", "=r,r"({{i64|i32}} %{{.*}})
14 asm volatile ("" : "=r"(ret
) : "r"(x
));
18 long test_cr(long x
) {
19 // CHECK-LABEL: define{{.*}} {{i64|i32}} @test_cr(
20 // CHECK: call {{i64|i32}} asm sideeffect "", "=^cr,^cr"({{i64|i32}} %{{.*}})
22 asm volatile ("" : "=cr"(ret
) : "cr"(x
));
28 void test_cf(float f
, double d
) {
29 // CHECK-LABEL: define{{.*}} void @test_cf(
30 // CHECK: call float asm sideeffect "", "=^cf,^cf"(float %{{.*}})
31 asm volatile("" : "=cf"(cf
) : "cf"(f
));
32 // CHECK: call double asm sideeffect "", "=^cf,^cf"(double %{{.*}})
33 asm volatile("" : "=cf"(cd
) : "cf"(d
));
36 #if __riscv_xlen == 32
37 typedef long long double_xlen_t
;
38 #elif __riscv_xlen == 64
39 typedef __int128_t double_xlen_t
;
41 double_xlen_t
test_R_wide_scalar(double_xlen_t p
) {
42 // CHECK-LABEL: define{{.*}} {{i128|i64}} @test_R_wide_scalar(
43 // CHECK: call {{i128|i64}} asm sideeffect "", "=R,R"({{i128|i64}} %{{.*}})
45 asm volatile("" : "=R"(ret
) : "R"(p
));
50 // CHECK-LABEL: define{{.*}} void @test_I()
51 // CHECK: call void asm sideeffect "", "I"(i32 2047)
52 asm volatile ("" :: "I"(2047));
53 // CHECK: call void asm sideeffect "", "I"(i32 -2048)
54 asm volatile ("" :: "I"(-2048));
58 // CHECK-LABEL: define{{.*}} void @test_J()
59 // CHECK: call void asm sideeffect "", "J"(i32 0)
60 asm volatile ("" :: "J"(0));
64 // CHECK-LABEL: define{{.*}} void @test_K()
65 // CHECK: call void asm sideeffect "", "K"(i32 31)
66 asm volatile ("" :: "K"(31));
67 // CHECK: call void asm sideeffect "", "K"(i32 0)
68 asm volatile ("" :: "K"(0));
74 // CHECK-LABEL: define{{.*}} void @test_f()
75 // CHECK: [[FLT_ARG:%[a-zA-Z_0-9]+]] = load float, ptr @f
76 // CHECK: call void asm sideeffect "", "f"(float [[FLT_ARG]])
77 asm volatile ("" :: "f"(f
));
78 // CHECK: [[FLT_ARG:%[a-zA-Z_0-9]+]] = load double, ptr @d
79 // CHECK: call void asm sideeffect "", "f"(double [[FLT_ARG]])
80 asm volatile ("" :: "f"(d
));
84 // CHECK-LABEL: define{{.*}} void @test_A(ptr noundef %p)
85 // CHECK: call void asm sideeffect "", "*A"(ptr elementtype(i32) %p)
86 asm volatile("" :: "A"(*p
));
89 extern int var
, arr
[2][2];
90 struct Pair
{ int a
, b
; } pair
;
92 // CHECK-LABEL: test_s(
93 // CHECK: call void asm sideeffect "// $0 $1 $2", "s,s,s"(ptr nonnull @var, ptr nonnull getelementptr inbounds nuw (i8, ptr @arr, {{.*}}), ptr nonnull @test_s)
94 // CHECK: call void asm sideeffect "// $0", "s"(ptr nonnull getelementptr inbounds nuw (i8, ptr @pair, {{.*}}))
95 // CHECK: call void asm sideeffect "// $0 $1 $2", "S,S,S"(ptr nonnull @var, ptr nonnull getelementptr inbounds nuw (i8, ptr @arr, {{.*}}), ptr nonnull @test_s)
97 asm("// %0 %1 %2" :: "s"(&var
), "s"(&arr
[1][1]), "s"(test_s
));
98 asm("// %0" :: "s"(&pair
.b
));
100 asm("// %0 %1 %2" :: "S"(&var
), "S"(&arr
[1][1]), "S"(test_s
));
103 // CHECK-LABEL: test_modifiers(
104 // CHECK: call void asm sideeffect "// ${0:i} ${1:i}", "r,r"({{i32|i64}} %val, i32 37)
105 // CHECK: call void asm sideeffect "// ${0:z} ${1:z}", "i,i"(i32 0, i32 1)
106 // CHECK: call void asm sideeffect "// ${0:N}", "r"({{i32|i64}} %val)
107 void test_modifiers(long val
) {
108 asm volatile("// %i0 %i1" :: "r"(val
), "r"(37));
109 asm volatile("// %z0 %z1" :: "i"(0), "i"(1));
110 asm volatile("// %N0" :: "r"(val
));