1 | //===------ SemaSystemZ.cpp ------ SystemZ 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 SystemZ. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "clang/Sema/SemaSystemZ.h" |
14 | #include "clang/Basic/DiagnosticSema.h" |
15 | #include "clang/Basic/TargetBuiltins.h" |
16 | #include "clang/Sema/Sema.h" |
17 | #include "llvm/ADT/APSInt.h" |
18 | #include <optional> |
19 | |
20 | namespace clang { |
21 | |
22 | SemaSystemZ::SemaSystemZ(Sema &S) : SemaBase(S) {} |
23 | |
24 | bool SemaSystemZ::CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, |
25 | CallExpr *TheCall) { |
26 | if (BuiltinID == SystemZ::BI__builtin_tabort) { |
27 | Expr *Arg = TheCall->getArg(Arg: 0); |
28 | if (std::optional<llvm::APSInt> AbortCode = |
29 | Arg->getIntegerConstantExpr(Ctx: getASTContext())) |
30 | if (AbortCode->getSExtValue() >= 0 && AbortCode->getSExtValue() < 256) |
31 | return Diag(Loc: Arg->getBeginLoc(), DiagID: diag::err_systemz_invalid_tabort_code) |
32 | << Arg->getSourceRange(); |
33 | } |
34 | |
35 | // For intrinsics which take an immediate value as part of the instruction, |
36 | // range check them here. |
37 | unsigned i = 0, l = 0, u = 0; |
38 | switch (BuiltinID) { |
39 | default: return false; |
40 | case SystemZ::BI__builtin_s390_lcbb: i = 1; l = 0; u = 15; break; |
41 | case SystemZ::BI__builtin_s390_verimb: |
42 | case SystemZ::BI__builtin_s390_verimh: |
43 | case SystemZ::BI__builtin_s390_verimf: |
44 | case SystemZ::BI__builtin_s390_verimg: i = 3; l = 0; u = 255; break; |
45 | case SystemZ::BI__builtin_s390_vfaeb: |
46 | case SystemZ::BI__builtin_s390_vfaeh: |
47 | case SystemZ::BI__builtin_s390_vfaef: |
48 | case SystemZ::BI__builtin_s390_vfaebs: |
49 | case SystemZ::BI__builtin_s390_vfaehs: |
50 | case SystemZ::BI__builtin_s390_vfaefs: |
51 | case SystemZ::BI__builtin_s390_vfaezb: |
52 | case SystemZ::BI__builtin_s390_vfaezh: |
53 | case SystemZ::BI__builtin_s390_vfaezf: |
54 | case SystemZ::BI__builtin_s390_vfaezbs: |
55 | case SystemZ::BI__builtin_s390_vfaezhs: |
56 | case SystemZ::BI__builtin_s390_vfaezfs: i = 2; l = 0; u = 15; break; |
57 | case SystemZ::BI__builtin_s390_vfisb: |
58 | case SystemZ::BI__builtin_s390_vfidb: |
59 | return SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: 1, Low: 0, High: 15) || |
60 | SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: 2, Low: 0, High: 15); |
61 | case SystemZ::BI__builtin_s390_vftcisb: |
62 | case SystemZ::BI__builtin_s390_vftcidb: i = 1; l = 0; u = 4095; break; |
63 | case SystemZ::BI__builtin_s390_vlbb: i = 1; l = 0; u = 15; break; |
64 | case SystemZ::BI__builtin_s390_vpdi: i = 2; l = 0; u = 15; break; |
65 | case SystemZ::BI__builtin_s390_vsldb: i = 2; l = 0; u = 15; break; |
66 | case SystemZ::BI__builtin_s390_vstrcb: |
67 | case SystemZ::BI__builtin_s390_vstrch: |
68 | case SystemZ::BI__builtin_s390_vstrcf: |
69 | case SystemZ::BI__builtin_s390_vstrczb: |
70 | case SystemZ::BI__builtin_s390_vstrczh: |
71 | case SystemZ::BI__builtin_s390_vstrczf: |
72 | case SystemZ::BI__builtin_s390_vstrcbs: |
73 | case SystemZ::BI__builtin_s390_vstrchs: |
74 | case SystemZ::BI__builtin_s390_vstrcfs: |
75 | case SystemZ::BI__builtin_s390_vstrczbs: |
76 | case SystemZ::BI__builtin_s390_vstrczhs: |
77 | case SystemZ::BI__builtin_s390_vstrczfs: i = 3; l = 0; u = 15; break; |
78 | case SystemZ::BI__builtin_s390_vmslg: i = 3; l = 0; u = 15; break; |
79 | case SystemZ::BI__builtin_s390_vfminsb: |
80 | case SystemZ::BI__builtin_s390_vfmaxsb: |
81 | case SystemZ::BI__builtin_s390_vfmindb: |
82 | case SystemZ::BI__builtin_s390_vfmaxdb: i = 2; l = 0; u = 15; break; |
83 | case SystemZ::BI__builtin_s390_vsld: i = 2; l = 0; u = 7; break; |
84 | case SystemZ::BI__builtin_s390_vsrd: i = 2; l = 0; u = 7; break; |
85 | case SystemZ::BI__builtin_s390_vclfnhs: |
86 | case SystemZ::BI__builtin_s390_vclfnls: |
87 | case SystemZ::BI__builtin_s390_vcfn: |
88 | case SystemZ::BI__builtin_s390_vcnf: i = 1; l = 0; u = 15; break; |
89 | case SystemZ::BI__builtin_s390_vcrnfs: i = 2; l = 0; u = 15; break; |
90 | } |
91 | return SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: i, Low: l, High: u); |
92 | } |
93 | |
94 | } // namespace clang |
95 | |