clang  20.0.0git
SemaMIPS.cpp
Go to the documentation of this file.
1 //===------ SemaMIPS.cpp -------- MIPS target-specific routines -----------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements semantic analysis functions specific to MIPS.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "clang/Sema/SemaMIPS.h"
16 #include "clang/Basic/TargetInfo.h"
17 #include "clang/Sema/Attr.h"
18 #include "clang/Sema/ParsedAttr.h"
19 #include "clang/Sema/Sema.h"
20 
21 namespace clang {
22 
24 
26  unsigned BuiltinID,
27  CallExpr *TheCall) {
28  return CheckMipsBuiltinCpu(TI, BuiltinID, TheCall) ||
29  CheckMipsBuiltinArgument(BuiltinID, TheCall);
30 }
31 
32 bool SemaMIPS::CheckMipsBuiltinCpu(const TargetInfo &TI, unsigned BuiltinID,
33  CallExpr *TheCall) {
34 
35  if (Mips::BI__builtin_mips_addu_qb <= BuiltinID &&
36  BuiltinID <= Mips::BI__builtin_mips_lwx) {
37  if (!TI.hasFeature("dsp"))
38  return Diag(TheCall->getBeginLoc(), diag::err_mips_builtin_requires_dsp);
39  }
40 
41  if (Mips::BI__builtin_mips_absq_s_qb <= BuiltinID &&
42  BuiltinID <= Mips::BI__builtin_mips_subuh_r_qb) {
43  if (!TI.hasFeature("dspr2"))
44  return Diag(TheCall->getBeginLoc(),
45  diag::err_mips_builtin_requires_dspr2);
46  }
47 
48  if (Mips::BI__builtin_msa_add_a_b <= BuiltinID &&
49  BuiltinID <= Mips::BI__builtin_msa_xori_b) {
50  if (!TI.hasFeature("msa"))
51  return Diag(TheCall->getBeginLoc(), diag::err_mips_builtin_requires_msa);
52  }
53 
54  return false;
55 }
56 
57 // CheckMipsBuiltinArgument - Checks the constant value passed to the
58 // intrinsic is correct. The switch statement is ordered by DSP, MSA. The
59 // ordering for DSP is unspecified. MSA is ordered by the data format used
60 // by the underlying instruction i.e., df/m, df/n and then by size.
61 //
62 // FIXME: The size tests here should instead be tablegen'd along with the
63 // definitions from include/clang/Basic/BuiltinsMips.def.
64 // FIXME: GCC is strict on signedness for some of these intrinsics, we should
65 // be too.
66 bool SemaMIPS::CheckMipsBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall) {
67  unsigned i = 0, l = 0, u = 0, m = 0;
68  switch (BuiltinID) {
69  default: return false;
70  case Mips::BI__builtin_mips_wrdsp: i = 1; l = 0; u = 63; break;
71  case Mips::BI__builtin_mips_rddsp: i = 0; l = 0; u = 63; break;
72  case Mips::BI__builtin_mips_append: i = 2; l = 0; u = 31; break;
73  case Mips::BI__builtin_mips_balign: i = 2; l = 0; u = 3; break;
74  case Mips::BI__builtin_mips_precr_sra_ph_w: i = 2; l = 0; u = 31; break;
75  case Mips::BI__builtin_mips_precr_sra_r_ph_w: i = 2; l = 0; u = 31; break;
76  case Mips::BI__builtin_mips_prepend: i = 2; l = 0; u = 31; break;
77  // MSA intrinsics. Instructions (which the intrinsics maps to) which use the
78  // df/m field.
79  // These intrinsics take an unsigned 3 bit immediate.
80  case Mips::BI__builtin_msa_bclri_b:
81  case Mips::BI__builtin_msa_bnegi_b:
82  case Mips::BI__builtin_msa_bseti_b:
83  case Mips::BI__builtin_msa_sat_s_b:
84  case Mips::BI__builtin_msa_sat_u_b:
85  case Mips::BI__builtin_msa_slli_b:
86  case Mips::BI__builtin_msa_srai_b:
87  case Mips::BI__builtin_msa_srari_b:
88  case Mips::BI__builtin_msa_srli_b:
89  case Mips::BI__builtin_msa_srlri_b: i = 1; l = 0; u = 7; break;
90  case Mips::BI__builtin_msa_binsli_b:
91  case Mips::BI__builtin_msa_binsri_b: i = 2; l = 0; u = 7; break;
92  // These intrinsics take an unsigned 4 bit immediate.
93  case Mips::BI__builtin_msa_bclri_h:
94  case Mips::BI__builtin_msa_bnegi_h:
95  case Mips::BI__builtin_msa_bseti_h:
96  case Mips::BI__builtin_msa_sat_s_h:
97  case Mips::BI__builtin_msa_sat_u_h:
98  case Mips::BI__builtin_msa_slli_h:
99  case Mips::BI__builtin_msa_srai_h:
100  case Mips::BI__builtin_msa_srari_h:
101  case Mips::BI__builtin_msa_srli_h:
102  case Mips::BI__builtin_msa_srlri_h: i = 1; l = 0; u = 15; break;
103  case Mips::BI__builtin_msa_binsli_h:
104  case Mips::BI__builtin_msa_binsri_h: i = 2; l = 0; u = 15; break;
105  // These intrinsics take an unsigned 5 bit immediate.
106  // The first block of intrinsics actually have an unsigned 5 bit field,
107  // not a df/n field.
108  case Mips::BI__builtin_msa_cfcmsa:
109  case Mips::BI__builtin_msa_ctcmsa: i = 0; l = 0; u = 31; break;
110  case Mips::BI__builtin_msa_clei_u_b:
111  case Mips::BI__builtin_msa_clei_u_h:
112  case Mips::BI__builtin_msa_clei_u_w:
113  case Mips::BI__builtin_msa_clei_u_d:
114  case Mips::BI__builtin_msa_clti_u_b:
115  case Mips::BI__builtin_msa_clti_u_h:
116  case Mips::BI__builtin_msa_clti_u_w:
117  case Mips::BI__builtin_msa_clti_u_d:
118  case Mips::BI__builtin_msa_maxi_u_b:
119  case Mips::BI__builtin_msa_maxi_u_h:
120  case Mips::BI__builtin_msa_maxi_u_w:
121  case Mips::BI__builtin_msa_maxi_u_d:
122  case Mips::BI__builtin_msa_mini_u_b:
123  case Mips::BI__builtin_msa_mini_u_h:
124  case Mips::BI__builtin_msa_mini_u_w:
125  case Mips::BI__builtin_msa_mini_u_d:
126  case Mips::BI__builtin_msa_addvi_b:
127  case Mips::BI__builtin_msa_addvi_h:
128  case Mips::BI__builtin_msa_addvi_w:
129  case Mips::BI__builtin_msa_addvi_d:
130  case Mips::BI__builtin_msa_bclri_w:
131  case Mips::BI__builtin_msa_bnegi_w:
132  case Mips::BI__builtin_msa_bseti_w:
133  case Mips::BI__builtin_msa_sat_s_w:
134  case Mips::BI__builtin_msa_sat_u_w:
135  case Mips::BI__builtin_msa_slli_w:
136  case Mips::BI__builtin_msa_srai_w:
137  case Mips::BI__builtin_msa_srari_w:
138  case Mips::BI__builtin_msa_srli_w:
139  case Mips::BI__builtin_msa_srlri_w:
140  case Mips::BI__builtin_msa_subvi_b:
141  case Mips::BI__builtin_msa_subvi_h:
142  case Mips::BI__builtin_msa_subvi_w:
143  case Mips::BI__builtin_msa_subvi_d: i = 1; l = 0; u = 31; break;
144  case Mips::BI__builtin_msa_binsli_w:
145  case Mips::BI__builtin_msa_binsri_w: i = 2; l = 0; u = 31; break;
146  // These intrinsics take an unsigned 6 bit immediate.
147  case Mips::BI__builtin_msa_bclri_d:
148  case Mips::BI__builtin_msa_bnegi_d:
149  case Mips::BI__builtin_msa_bseti_d:
150  case Mips::BI__builtin_msa_sat_s_d:
151  case Mips::BI__builtin_msa_sat_u_d:
152  case Mips::BI__builtin_msa_slli_d:
153  case Mips::BI__builtin_msa_srai_d:
154  case Mips::BI__builtin_msa_srari_d:
155  case Mips::BI__builtin_msa_srli_d:
156  case Mips::BI__builtin_msa_srlri_d: i = 1; l = 0; u = 63; break;
157  case Mips::BI__builtin_msa_binsli_d:
158  case Mips::BI__builtin_msa_binsri_d: i = 2; l = 0; u = 63; break;
159  // These intrinsics take a signed 5 bit immediate.
160  case Mips::BI__builtin_msa_ceqi_b:
161  case Mips::BI__builtin_msa_ceqi_h:
162  case Mips::BI__builtin_msa_ceqi_w:
163  case Mips::BI__builtin_msa_ceqi_d:
164  case Mips::BI__builtin_msa_clti_s_b:
165  case Mips::BI__builtin_msa_clti_s_h:
166  case Mips::BI__builtin_msa_clti_s_w:
167  case Mips::BI__builtin_msa_clti_s_d:
168  case Mips::BI__builtin_msa_clei_s_b:
169  case Mips::BI__builtin_msa_clei_s_h:
170  case Mips::BI__builtin_msa_clei_s_w:
171  case Mips::BI__builtin_msa_clei_s_d:
172  case Mips::BI__builtin_msa_maxi_s_b:
173  case Mips::BI__builtin_msa_maxi_s_h:
174  case Mips::BI__builtin_msa_maxi_s_w:
175  case Mips::BI__builtin_msa_maxi_s_d:
176  case Mips::BI__builtin_msa_mini_s_b:
177  case Mips::BI__builtin_msa_mini_s_h:
178  case Mips::BI__builtin_msa_mini_s_w:
179  case Mips::BI__builtin_msa_mini_s_d: i = 1; l = -16; u = 15; break;
180  // These intrinsics take an unsigned 8 bit immediate.
181  case Mips::BI__builtin_msa_andi_b:
182  case Mips::BI__builtin_msa_nori_b:
183  case Mips::BI__builtin_msa_ori_b:
184  case Mips::BI__builtin_msa_shf_b:
185  case Mips::BI__builtin_msa_shf_h:
186  case Mips::BI__builtin_msa_shf_w:
187  case Mips::BI__builtin_msa_xori_b: i = 1; l = 0; u = 255; break;
188  case Mips::BI__builtin_msa_bseli_b:
189  case Mips::BI__builtin_msa_bmnzi_b:
190  case Mips::BI__builtin_msa_bmzi_b: i = 2; l = 0; u = 255; break;
191  // df/n format
192  // These intrinsics take an unsigned 4 bit immediate.
193  case Mips::BI__builtin_msa_copy_s_b:
194  case Mips::BI__builtin_msa_copy_u_b:
195  case Mips::BI__builtin_msa_insve_b:
196  case Mips::BI__builtin_msa_splati_b: i = 1; l = 0; u = 15; break;
197  case Mips::BI__builtin_msa_sldi_b: i = 2; l = 0; u = 15; break;
198  // These intrinsics take an unsigned 3 bit immediate.
199  case Mips::BI__builtin_msa_copy_s_h:
200  case Mips::BI__builtin_msa_copy_u_h:
201  case Mips::BI__builtin_msa_insve_h:
202  case Mips::BI__builtin_msa_splati_h: i = 1; l = 0; u = 7; break;
203  case Mips::BI__builtin_msa_sldi_h: i = 2; l = 0; u = 7; break;
204  // These intrinsics take an unsigned 2 bit immediate.
205  case Mips::BI__builtin_msa_copy_s_w:
206  case Mips::BI__builtin_msa_copy_u_w:
207  case Mips::BI__builtin_msa_insve_w:
208  case Mips::BI__builtin_msa_splati_w: i = 1; l = 0; u = 3; break;
209  case Mips::BI__builtin_msa_sldi_w: i = 2; l = 0; u = 3; break;
210  // These intrinsics take an unsigned 1 bit immediate.
211  case Mips::BI__builtin_msa_copy_s_d:
212  case Mips::BI__builtin_msa_copy_u_d:
213  case Mips::BI__builtin_msa_insve_d:
214  case Mips::BI__builtin_msa_splati_d: i = 1; l = 0; u = 1; break;
215  case Mips::BI__builtin_msa_sldi_d: i = 2; l = 0; u = 1; break;
216  // Memory offsets and immediate loads.
217  // These intrinsics take a signed 10 bit immediate.
218  case Mips::BI__builtin_msa_ldi_b: i = 0; l = -128; u = 255; break;
219  case Mips::BI__builtin_msa_ldi_h:
220  case Mips::BI__builtin_msa_ldi_w:
221  case Mips::BI__builtin_msa_ldi_d: i = 0; l = -512; u = 511; break;
222  case Mips::BI__builtin_msa_ld_b: i = 1; l = -512; u = 511; m = 1; break;
223  case Mips::BI__builtin_msa_ld_h: i = 1; l = -1024; u = 1022; m = 2; break;
224  case Mips::BI__builtin_msa_ld_w: i = 1; l = -2048; u = 2044; m = 4; break;
225  case Mips::BI__builtin_msa_ld_d: i = 1; l = -4096; u = 4088; m = 8; break;
226  case Mips::BI__builtin_msa_ldr_d: i = 1; l = -4096; u = 4088; m = 8; break;
227  case Mips::BI__builtin_msa_ldr_w: i = 1; l = -2048; u = 2044; m = 4; break;
228  case Mips::BI__builtin_msa_st_b: i = 2; l = -512; u = 511; m = 1; break;
229  case Mips::BI__builtin_msa_st_h: i = 2; l = -1024; u = 1022; m = 2; break;
230  case Mips::BI__builtin_msa_st_w: i = 2; l = -2048; u = 2044; m = 4; break;
231  case Mips::BI__builtin_msa_st_d: i = 2; l = -4096; u = 4088; m = 8; break;
232  case Mips::BI__builtin_msa_str_d: i = 2; l = -4096; u = 4088; m = 8; break;
233  case Mips::BI__builtin_msa_str_w: i = 2; l = -2048; u = 2044; m = 4; break;
234  }
235 
236  if (!m)
237  return SemaRef.BuiltinConstantArgRange(TheCall, i, l, u);
238 
239  return SemaRef.BuiltinConstantArgRange(TheCall, i, l, u) ||
240  SemaRef.BuiltinConstantArgMultiple(TheCall, i, m);
241 }
242 
244  // Only one optional argument permitted.
245  if (AL.getNumArgs() > 1) {
246  Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << AL << 1;
247  return;
248  }
249 
250  StringRef Str;
251  SourceLocation ArgLoc;
252 
253  if (AL.getNumArgs() == 0)
254  Str = "";
255  else if (!SemaRef.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc))
256  return;
257 
258  // Semantic checks for a function with the 'interrupt' attribute for MIPS:
259  // a) Must be a function.
260  // b) Must have no parameters.
261  // c) Must have the 'void' return type.
262  // d) Cannot have the 'mips16' attribute, as that instruction set
263  // lacks the 'eret' instruction.
264  // e) The attribute itself must either have no argument or one of the
265  // valid interrupt types, see [MipsInterruptDocs].
266 
268  Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
270  return;
271  }
272 
274  Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
275  << /*MIPS*/ 0 << 0;
276  return;
277  }
278 
279  if (!getFunctionOrMethodResultType(D)->isVoidType()) {
280  Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
281  << /*MIPS*/ 0 << 1;
282  return;
283  }
284 
285  // We still have to do this manually because the Interrupt attributes are
286  // a bit special due to sharing their spellings across targets.
287  if (checkAttrMutualExclusion<Mips16Attr>(*this, D, AL))
288  return;
289 
290  MipsInterruptAttr::InterruptType Kind;
291  if (!MipsInterruptAttr::ConvertStrToInterruptType(Str, Kind)) {
292  Diag(AL.getLoc(), diag::warn_attribute_type_not_supported)
293  << AL << "'" + std::string(Str) + "'";
294  return;
295  }
296 
297  D->addAttr(::new (getASTContext())
298  MipsInterruptAttr(getASTContext(), AL, Kind));
299 }
300 
301 } // namespace clang
const Decl * D
enum clang::sema::@1659::IndirectLocalPathEntry::EntryKind Kind
This file declares semantic analysis functions specific to MIPS.
Enumerates target-specific builtins in their own namespaces within namespace clang.
SourceLocation getLoc() const
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2882
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Expr.cpp:1693
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
ParsedAttr - Represents a syntactic attribute.
Definition: ParsedAttr.h:129
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this attribute.
Definition: ParsedAttr.h:386
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition: SemaBase.cpp:64
ASTContext & getASTContext() const
Definition: SemaBase.cpp:9
Sema & SemaRef
Definition: SemaBase.h:40
bool CheckMipsBuiltinCpu(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
Definition: SemaMIPS.cpp:32
bool CheckMipsBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
Definition: SemaMIPS.cpp:25
bool CheckMipsBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall)
Definition: SemaMIPS.cpp:66
void handleInterruptAttr(Decl *D, const ParsedAttr &AL)
Definition: SemaMIPS.cpp:243
SemaMIPS(Sema &S)
Definition: SemaMIPS.cpp:23
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:493
bool BuiltinConstantArgMultiple(CallExpr *TheCall, int ArgNum, unsigned Multiple)
BuiltinConstantArgMultiple - Handle a check if argument ArgNum of CallExpr TheCall is a constant expr...
bool BuiltinConstantArgRange(CallExpr *TheCall, int ArgNum, int Low, int High, bool RangeIsError=true)
BuiltinConstantArgRange - Handle a check if argument ArgNum of CallExpr TheCall is a constant express...
bool checkStringLiteralArgumentAttr(const AttributeCommonInfo &CI, const Expr *E, StringRef &Str, SourceLocation *ArgLocation=nullptr)
Check if the argument E is a ASCII string literal.
Encodes a location in the source.
Exposes information about the current target.
Definition: TargetInfo.h:218
virtual bool hasFeature(StringRef Feature) const
Determine whether the given target has the given feature.
Definition: TargetInfo.h:1487
Defines the clang::TargetInfo interface.
The JSON file list parser is used to communicate input to InstallAPI.
@ ExpectedFunctionOrMethod
Definition: ParsedAttr.h:1099
QualType getFunctionOrMethodResultType(const Decl *D)
Definition: Attr.h:98
bool isFuncOrMethodForAttrSubject(const Decl *D)
isFuncOrMethodForAttrSubject - Return true if the given decl has function type (function or function-...
Definition: Attr.h:34
bool hasFunctionProto(const Decl *D)
hasFunctionProto - Return true if the given decl has a argument information.
Definition: Attr.h:55
unsigned getFunctionOrMethodNumParams(const Decl *D)
getFunctionOrMethodNumParams - Return number of function or method parameters.
Definition: Attr.h:64