"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
- "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"};
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+
+ // Vector registers
+ "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
+ "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
+ "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
+ "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"};
return llvm::makeArrayRef(GCCRegNames);
}
// An address that is held in a general-purpose register.
Info.setAllowsMemory();
return true;
+ case 'v':
+ // A vector register.
+ if (Name[1] == 'r' || Name[1] == 'm') {
+ Info.setAllowsRegister();
+ Name += 1;
+ return true;
+ }
+ return false;
+ }
+}
+
+std::string RISCVTargetInfo::convertConstraint(const char *&Constraint) const {
+ std::string R;
+ switch (*Constraint) {
+ case 'v':
+ R = std::string("v");
+ Constraint += 1;
+ break;
+ default:
+ R = TargetInfo::convertConstraint(Constraint);
+ break;
}
+ return R;
}
void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts,
--- /dev/null
+// RUN: %clang_cc1 -triple riscv32 -target-feature +experimental-v \
+// RUN: -O2 -emit-llvm %s -o - \
+// RUN: | FileCheck %s
+// RUN: %clang_cc1 -triple riscv64 -target-feature +experimental-v \
+// RUN: -O2 -emit-llvm %s -o - \
+// RUN: | FileCheck %s
+
+// Test RISC-V V-extension specific inline assembly constraints.
+#include <riscv_vector.h>
+
+void test_v_reg() {
+ asm volatile(
+ "vsetvli x1, x0, e32,m2,tu,mu\n"
+ "vadd.vv v1, v2, v3, v0.t"
+ :
+ :
+ : "v1", "x1");
+// CHECK-LABEL: define{{.*}} @test_v_reg
+// CHECK: "~{v1},~{x1}"
+}
+
+vint32m1_t test_vr(vint32m1_t a, vint32m1_t b) {
+// CHECK-LABEL: define{{.*}} @test_vr
+// CHECK: %0 = tail call <vscale x 2 x i32> asm sideeffect "vadd.vv $0, $1, $2", "=v,v,v"(<vscale x 2 x i32> %a, <vscale x 2 x i32> %b)
+ vint32m1_t ret;
+ asm volatile ("vadd.vv %0, %1, %2" : "=vr"(ret) : "vr"(a), "vr"(b));
+ return ret;
+}
+
+vbool1_t test_vm(vbool1_t a, vbool1_t b) {
+// CHECK-LABEL: define{{.*}} @test_vm
+// CHECK: %0 = tail call <vscale x 64 x i1> asm sideeffect "vmand.mm $0, $1, $2", "=v,v,v"(<vscale x 64 x i1> %a, <vscale x 64 x i1> %b)
+ vbool1_t ret;
+ asm volatile ("vmand.mm %0, %1, %2" : "=vm"(ret) : "vm"(a), "vm"(b));
+ return ret;
+}