1 // RUN: %clang_cc1 -triple riscv32 -O2 -emit-llvm %s -o - \ 2 // RUN: | FileCheck %s 3 // RUN: %clang_cc1 -triple riscv64 -O2 -emit-llvm %s -o - \ 4 // RUN: | FileCheck %s 5 6 // Test RISC-V specific inline assembly constraints and modifiers. 7 8 long test_r(long x) { 9 // CHECK-LABEL: define{{.*}} {{i64|i32}} @test_r( 10 // CHECK: call {{i64|i32}} asm sideeffect "", "=r,r"({{i64|i32}} %{{.*}}) 11 long ret; 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)); 15 return ret; 16 } 17 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}} %{{.*}}) 21 long ret; 22 asm volatile ("" : "=cr"(ret) : "cr"(x)); 23 return ret; 24 } 25 26 float cf; 27 double cd; 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)); 34 } 35 36 #if __riscv_xlen == 32 37 typedef long long double_xlen_t; 38 #elif __riscv_xlen == 64 39 typedef __int128_t double_xlen_t; 40 #endif 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}} %{{.*}}) 44 double_xlen_t ret; 45 asm volatile("" : "=R"(ret) : "R"(p)); 46 return ret; 47 } 48 49 void test_I(void) { 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)); 55 } 56 57 void test_J(void) { 58 // CHECK-LABEL: define{{.*}} void @test_J() 59 // CHECK: call void asm sideeffect "", "J"(i32 0) 60 asm volatile ("" :: "J"(0)); 61 } 62 63 void test_K(void) { 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)); 69 } 70 71 float f; 72 double d; 73 void test_f(void) { 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)); 81 } 82 83 void test_A(int *p) { 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)); 87 } 88 89 extern int var, arr[2][2]; 90 struct Pair { int a, b; } pair; 91 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) 96 void test_s(void) { 97 asm("// %0 %1 %2" :: "s"(&var), "s"(&arr[1][1]), "s"(test_s)); 98 asm("// %0" :: "s"(&pair.b)); 99 100 asm("// %0 %1 %2" :: "S"(&var), "S"(&arr[1][1]), "S"(test_s)); 101 } 102 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)); 111 } 112