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
20namespace clang {
21
22SemaSystemZ::SemaSystemZ(Sema &S) : SemaBase(S) {}
23
24bool 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