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(0); 28 if (std::optional<llvm::APSInt> AbortCode = 29 Arg->getIntegerConstantExpr(getASTContext())) 30 if (AbortCode->getSExtValue() >= 0 && AbortCode->getSExtValue() < 256) 31 return Diag(Arg->getBeginLoc(), 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, 1, 0, 15) || 60 SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 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, i, l, u); 92 } 93 94 } // namespace clang 95