diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -8742,6 +8742,12 @@ "this builtin is only available on 32-bit targets">; def err_builtin_x64_aarch64_only : Error< "this builtin is only available on x86-64 and aarch64 targets">; +def err_mips_builtin_requires_dsp : Error< + "this builtin requires 'dsp' ASE, please use -mdsp">; +def err_mips_builtin_requires_dspr2 : Error< + "this builtin requires 'dsp r2' ASE, please use -mdspr2">; +def err_mips_builtin_requires_msa : Error< + "this builtin requires 'msa' ASE, please use -mmsa">; def err_ppc_builtin_only_on_pwr7 : Error< "this builtin is only valid on POWER7 or later CPUs">; def err_x86_builtin_invalid_rounding : Error< diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -11282,6 +11282,8 @@ bool CheckHexagonBuiltinCpu(unsigned BuiltinID, CallExpr *TheCall); bool CheckHexagonBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall); bool CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckMipsBuiltinCpu(unsigned BuiltinID, CallExpr *TheCall); + bool CheckMipsBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall); bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckX86BuiltinRoundingOrSAE(unsigned BuiltinID, CallExpr *TheCall); bool CheckX86BuiltinGatherScatterScale(unsigned BuiltinID, CallExpr *TheCall); diff --git a/clang/lib/Basic/Targets/Mips.cpp b/clang/lib/Basic/Targets/Mips.cpp --- a/clang/lib/Basic/Targets/Mips.cpp +++ b/clang/lib/Basic/Targets/Mips.cpp @@ -213,7 +213,10 @@ bool MipsTargetInfo::hasFeature(StringRef Feature) const { return llvm::StringSwitch(Feature) .Case("mips", true) + .Case("dsp", DspRev >= DSP1) + .Case("dspr2", DspRev >= DSP2) .Case("fp64", FPMode == FP64) + .Case("msa", HasMSA) .Default(false); } diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -3051,8 +3051,37 @@ CheckHexagonBuiltinArgument(BuiltinID, TheCall); } +bool Sema::CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { + return CheckMipsBuiltinCpu(BuiltinID, TheCall) || + CheckMipsBuiltinArgument(BuiltinID, TheCall); +} + +bool Sema::CheckMipsBuiltinCpu(unsigned BuiltinID, CallExpr *TheCall) { + const TargetInfo &TI = Context.getTargetInfo(); -// CheckMipsBuiltinFunctionCall - Checks the constant value passed to the + if (Mips::BI__builtin_mips_addu_qb <= BuiltinID && + BuiltinID <= Mips::BI__builtin_mips_lwx) { + if (!TI.hasFeature("dsp")) + return Diag(TheCall->getBeginLoc(), diag::err_mips_builtin_requires_dsp); + } + + if (Mips::BI__builtin_mips_absq_s_qb <= BuiltinID && + BuiltinID <= Mips::BI__builtin_mips_subuh_r_qb) { + if (!TI.hasFeature("dspr2")) + return Diag(TheCall->getBeginLoc(), + diag::err_mips_builtin_requires_dspr2); + } + + if (Mips::BI__builtin_msa_add_a_b <= BuiltinID && + BuiltinID <= Mips::BI__builtin_msa_xori_b) { + if (!TI.hasFeature("msa")) + return Diag(TheCall->getBeginLoc(), diag::err_mips_builtin_requires_msa); + } + + return false; +} + +// CheckMipsBuiltinArgument - Checks the constant value passed to the // intrinsic is correct. The switch statement is ordered by DSP, MSA. The // ordering for DSP is unspecified. MSA is ordered by the data format used // by the underlying instruction i.e., df/m, df/n and then by size. @@ -3061,7 +3090,7 @@ // definitions from include/clang/Basic/BuiltinsMips.def. // FIXME: GCC is strict on signedness for some of these intrinsics, we should // be too. -bool Sema::CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { +bool Sema::CheckMipsBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall) { unsigned i = 0, l = 0, u = 0, m = 0; switch (BuiltinID) { default: return false; diff --git a/clang/test/CodeGen/builtins-mips-args.c b/clang/test/CodeGen/builtins-mips-args.c --- a/clang/test/CodeGen/builtins-mips-args.c +++ b/clang/test/CodeGen/builtins-mips-args.c @@ -1,5 +1,6 @@ // REQUIRES: mips-registered-target -// RUN: %clang_cc1 -triple mips-unknown-linux-gnu -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple mips-unknown-linux-gnu -target-feature +dspr2 \ +// RUN: -fsyntax-only -verify %s void foo() { // MIPS DSP Rev 1 diff --git a/clang/test/CodeGen/builtins-mips.c b/clang/test/CodeGen/builtins-mips.c --- a/clang/test/CodeGen/builtins-mips.c +++ b/clang/test/CodeGen/builtins-mips.c @@ -1,5 +1,6 @@ // REQUIRES: mips-registered-target -// RUN: %clang_cc1 -triple mips-unknown-linux-gnu -emit-llvm %s -o - \ +// RUN: %clang_cc1 -triple mips-unknown-linux-gnu -emit-llvm %s \ +// RUN: -target-feature +dspr2 -o - \ // RUN: | FileCheck %s typedef int q31; diff --git a/clang/test/Sema/builtins-mips-features.c b/clang/test/Sema/builtins-mips-features.c new file mode 100644 --- /dev/null +++ b/clang/test/Sema/builtins-mips-features.c @@ -0,0 +1,37 @@ +// REQUIRES: mips-registered-target +// RUN: %clang_cc1 -triple mips64 -fsyntax-only -verify %s + +typedef signed char v4i8 __attribute__ ((vector_size(4))); +typedef signed char v4q7 __attribute__ ((vector_size(4))); +typedef signed char v16i8 __attribute__((vector_size(16), aligned(16))); +typedef unsigned char v16u8 __attribute__((vector_size(16), aligned(16))); + +void dsp() { + v4i8 a; + void* p; + + // expected-error@+1 {{this builtin requires 'dsp' ASE, please use -mdsp}} + __builtin_mips_addu_qb(a, a); + // expected-error@+1 {{this builtin requires 'dsp' ASE, please use -mdsp}} + __builtin_mips_lwx(p, 32); +} + +void dspr2() { + v4i8 a; + v4q7 b; + + // expected-error@+1 {{this builtin requires 'dsp r2' ASE, please use -mdspr2}} + __builtin_mips_absq_s_qb(b); + // expected-error@+1 {{this builtin requires 'dsp r2' ASE, please use -mdspr2}} + __builtin_mips_subuh_r_qb(a, a); +} + +void msa() { + v16i8 a; + v16u8 b; + + // expected-error@+1 {{this builtin requires 'msa' ASE, please use -mmsa}} + __builtin_msa_add_a_b(a, a); + // expected-error@+1 {{this builtin requires 'msa' ASE, please use -mmsa}} + __builtin_msa_xori_b(b, 5); +}