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 22*0fca6ea1SDimitry Andric SemaSystemZ::SemaSystemZ(Sema &S) : SemaBase(S) {} 23*0fca6ea1SDimitry Andric 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