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