[RISCV] Add inline asm constraint 'vr' and 'vm' in Clang for RISC-V 'V'.

Add asm constraint 'vr' for vector registers.
Add asm constraint 'vm' for vector mask registers.

Differential Revision: https://reviews.llvm.org/D98616
This commit is contained in:
Hsiangkai Wang 2021-03-29 18:27:27 +08:00
parent fd94cfeeb5
commit 5821a58d8e
3 changed files with 67 additions and 1 deletions

View File

@ -31,7 +31,13 @@ ArrayRef<const char *> RISCVTargetInfo::getGCCRegNames() const {
"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);
}
@ -81,9 +87,31 @@ bool RISCVTargetInfo::validateAsmConstraint(
// 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,
MacroBuilder &Builder) const {
Builder.defineMacro("__ELF__");

View File

@ -97,6 +97,8 @@ public:
bool validateAsmConstraint(const char *&Name,
TargetInfo::ConstraintInfo &Info) const override;
std::string convertConstraint(const char *&Constraint) const override;
bool hasFeature(StringRef Feature) const override;
bool handleTargetFeatures(std::vector<std::string> &Features,

View File

@ -0,0 +1,36 @@
// 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;
}