1ed35a92cSVlad Serebrennikov //===------ SemaMIPS.cpp -------- MIPS target-specific routines -----------===// 2ed35a92cSVlad Serebrennikov // 3ed35a92cSVlad Serebrennikov // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4ed35a92cSVlad Serebrennikov // See https://llvm.org/LICENSE.txt for license information. 5ed35a92cSVlad Serebrennikov // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6ed35a92cSVlad Serebrennikov // 7ed35a92cSVlad Serebrennikov //===----------------------------------------------------------------------===// 8ed35a92cSVlad Serebrennikov // 9ed35a92cSVlad Serebrennikov // This file implements semantic analysis functions specific to MIPS. 10ed35a92cSVlad Serebrennikov // 11ed35a92cSVlad Serebrennikov //===----------------------------------------------------------------------===// 12ed35a92cSVlad Serebrennikov 13ed35a92cSVlad Serebrennikov #include "clang/Sema/SemaMIPS.h" 14ed35a92cSVlad Serebrennikov #include "clang/Basic/DiagnosticSema.h" 15ed35a92cSVlad Serebrennikov #include "clang/Basic/TargetBuiltins.h" 16*27d37ee4SVlad Serebrennikov #include "clang/Basic/TargetInfo.h" 176b755b0cSVlad Serebrennikov #include "clang/Sema/Attr.h" 186b755b0cSVlad Serebrennikov #include "clang/Sema/ParsedAttr.h" 19ed35a92cSVlad Serebrennikov #include "clang/Sema/Sema.h" 20ed35a92cSVlad Serebrennikov 21ed35a92cSVlad Serebrennikov namespace clang { 22ed35a92cSVlad Serebrennikov 23ed35a92cSVlad Serebrennikov SemaMIPS::SemaMIPS(Sema &S) : SemaBase(S) {} 24ed35a92cSVlad Serebrennikov 25ed35a92cSVlad Serebrennikov bool SemaMIPS::CheckMipsBuiltinFunctionCall(const TargetInfo &TI, 26ed35a92cSVlad Serebrennikov unsigned BuiltinID, 27ed35a92cSVlad Serebrennikov CallExpr *TheCall) { 28ed35a92cSVlad Serebrennikov return CheckMipsBuiltinCpu(TI, BuiltinID, TheCall) || 29ed35a92cSVlad Serebrennikov CheckMipsBuiltinArgument(BuiltinID, TheCall); 30ed35a92cSVlad Serebrennikov } 31ed35a92cSVlad Serebrennikov 32ed35a92cSVlad Serebrennikov bool SemaMIPS::CheckMipsBuiltinCpu(const TargetInfo &TI, unsigned BuiltinID, 33ed35a92cSVlad Serebrennikov CallExpr *TheCall) { 34ed35a92cSVlad Serebrennikov 35ed35a92cSVlad Serebrennikov if (Mips::BI__builtin_mips_addu_qb <= BuiltinID && 36ed35a92cSVlad Serebrennikov BuiltinID <= Mips::BI__builtin_mips_lwx) { 37ed35a92cSVlad Serebrennikov if (!TI.hasFeature("dsp")) 38ed35a92cSVlad Serebrennikov return Diag(TheCall->getBeginLoc(), diag::err_mips_builtin_requires_dsp); 39ed35a92cSVlad Serebrennikov } 40ed35a92cSVlad Serebrennikov 41ed35a92cSVlad Serebrennikov if (Mips::BI__builtin_mips_absq_s_qb <= BuiltinID && 42ed35a92cSVlad Serebrennikov BuiltinID <= Mips::BI__builtin_mips_subuh_r_qb) { 43ed35a92cSVlad Serebrennikov if (!TI.hasFeature("dspr2")) 44ed35a92cSVlad Serebrennikov return Diag(TheCall->getBeginLoc(), 45ed35a92cSVlad Serebrennikov diag::err_mips_builtin_requires_dspr2); 46ed35a92cSVlad Serebrennikov } 47ed35a92cSVlad Serebrennikov 48ed35a92cSVlad Serebrennikov if (Mips::BI__builtin_msa_add_a_b <= BuiltinID && 49ed35a92cSVlad Serebrennikov BuiltinID <= Mips::BI__builtin_msa_xori_b) { 50ed35a92cSVlad Serebrennikov if (!TI.hasFeature("msa")) 51ed35a92cSVlad Serebrennikov return Diag(TheCall->getBeginLoc(), diag::err_mips_builtin_requires_msa); 52ed35a92cSVlad Serebrennikov } 53ed35a92cSVlad Serebrennikov 54ed35a92cSVlad Serebrennikov return false; 55ed35a92cSVlad Serebrennikov } 56ed35a92cSVlad Serebrennikov 57ed35a92cSVlad Serebrennikov // CheckMipsBuiltinArgument - Checks the constant value passed to the 58ed35a92cSVlad Serebrennikov // intrinsic is correct. The switch statement is ordered by DSP, MSA. The 59ed35a92cSVlad Serebrennikov // ordering for DSP is unspecified. MSA is ordered by the data format used 60ed35a92cSVlad Serebrennikov // by the underlying instruction i.e., df/m, df/n and then by size. 61ed35a92cSVlad Serebrennikov // 62ed35a92cSVlad Serebrennikov // FIXME: The size tests here should instead be tablegen'd along with the 63ed35a92cSVlad Serebrennikov // definitions from include/clang/Basic/BuiltinsMips.def. 64ed35a92cSVlad Serebrennikov // FIXME: GCC is strict on signedness for some of these intrinsics, we should 65ed35a92cSVlad Serebrennikov // be too. 66ed35a92cSVlad Serebrennikov bool SemaMIPS::CheckMipsBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall) { 67ed35a92cSVlad Serebrennikov unsigned i = 0, l = 0, u = 0, m = 0; 68ed35a92cSVlad Serebrennikov switch (BuiltinID) { 69ed35a92cSVlad Serebrennikov default: return false; 70ed35a92cSVlad Serebrennikov case Mips::BI__builtin_mips_wrdsp: i = 1; l = 0; u = 63; break; 71ed35a92cSVlad Serebrennikov case Mips::BI__builtin_mips_rddsp: i = 0; l = 0; u = 63; break; 72ed35a92cSVlad Serebrennikov case Mips::BI__builtin_mips_append: i = 2; l = 0; u = 31; break; 73ed35a92cSVlad Serebrennikov case Mips::BI__builtin_mips_balign: i = 2; l = 0; u = 3; break; 74ed35a92cSVlad Serebrennikov case Mips::BI__builtin_mips_precr_sra_ph_w: i = 2; l = 0; u = 31; break; 75ed35a92cSVlad Serebrennikov case Mips::BI__builtin_mips_precr_sra_r_ph_w: i = 2; l = 0; u = 31; break; 76ed35a92cSVlad Serebrennikov case Mips::BI__builtin_mips_prepend: i = 2; l = 0; u = 31; break; 77ed35a92cSVlad Serebrennikov // MSA intrinsics. Instructions (which the intrinsics maps to) which use the 78ed35a92cSVlad Serebrennikov // df/m field. 79ed35a92cSVlad Serebrennikov // These intrinsics take an unsigned 3 bit immediate. 80ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_bclri_b: 81ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_bnegi_b: 82ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_bseti_b: 83ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_sat_s_b: 84ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_sat_u_b: 85ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_slli_b: 86ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_srai_b: 87ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_srari_b: 88ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_srli_b: 89ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_srlri_b: i = 1; l = 0; u = 7; break; 90ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_binsli_b: 91ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_binsri_b: i = 2; l = 0; u = 7; break; 92ed35a92cSVlad Serebrennikov // These intrinsics take an unsigned 4 bit immediate. 93ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_bclri_h: 94ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_bnegi_h: 95ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_bseti_h: 96ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_sat_s_h: 97ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_sat_u_h: 98ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_slli_h: 99ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_srai_h: 100ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_srari_h: 101ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_srli_h: 102ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_srlri_h: i = 1; l = 0; u = 15; break; 103ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_binsli_h: 104ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_binsri_h: i = 2; l = 0; u = 15; break; 105ed35a92cSVlad Serebrennikov // These intrinsics take an unsigned 5 bit immediate. 106ed35a92cSVlad Serebrennikov // The first block of intrinsics actually have an unsigned 5 bit field, 107ed35a92cSVlad Serebrennikov // not a df/n field. 108ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_cfcmsa: 109ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_ctcmsa: i = 0; l = 0; u = 31; break; 110ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_clei_u_b: 111ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_clei_u_h: 112ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_clei_u_w: 113ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_clei_u_d: 114ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_clti_u_b: 115ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_clti_u_h: 116ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_clti_u_w: 117ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_clti_u_d: 118ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_maxi_u_b: 119ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_maxi_u_h: 120ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_maxi_u_w: 121ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_maxi_u_d: 122ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_mini_u_b: 123ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_mini_u_h: 124ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_mini_u_w: 125ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_mini_u_d: 126ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_addvi_b: 127ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_addvi_h: 128ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_addvi_w: 129ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_addvi_d: 130ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_bclri_w: 131ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_bnegi_w: 132ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_bseti_w: 133ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_sat_s_w: 134ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_sat_u_w: 135ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_slli_w: 136ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_srai_w: 137ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_srari_w: 138ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_srli_w: 139ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_srlri_w: 140ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_subvi_b: 141ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_subvi_h: 142ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_subvi_w: 143ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_subvi_d: i = 1; l = 0; u = 31; break; 144ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_binsli_w: 145ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_binsri_w: i = 2; l = 0; u = 31; break; 146ed35a92cSVlad Serebrennikov // These intrinsics take an unsigned 6 bit immediate. 147ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_bclri_d: 148ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_bnegi_d: 149ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_bseti_d: 150ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_sat_s_d: 151ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_sat_u_d: 152ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_slli_d: 153ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_srai_d: 154ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_srari_d: 155ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_srli_d: 156ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_srlri_d: i = 1; l = 0; u = 63; break; 157ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_binsli_d: 158ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_binsri_d: i = 2; l = 0; u = 63; break; 159ed35a92cSVlad Serebrennikov // These intrinsics take a signed 5 bit immediate. 160ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_ceqi_b: 161ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_ceqi_h: 162ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_ceqi_w: 163ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_ceqi_d: 164ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_clti_s_b: 165ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_clti_s_h: 166ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_clti_s_w: 167ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_clti_s_d: 168ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_clei_s_b: 169ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_clei_s_h: 170ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_clei_s_w: 171ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_clei_s_d: 172ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_maxi_s_b: 173ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_maxi_s_h: 174ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_maxi_s_w: 175ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_maxi_s_d: 176ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_mini_s_b: 177ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_mini_s_h: 178ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_mini_s_w: 179ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_mini_s_d: i = 1; l = -16; u = 15; break; 180ed35a92cSVlad Serebrennikov // These intrinsics take an unsigned 8 bit immediate. 181ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_andi_b: 182ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_nori_b: 183ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_ori_b: 184ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_shf_b: 185ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_shf_h: 186ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_shf_w: 187ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_xori_b: i = 1; l = 0; u = 255; break; 188ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_bseli_b: 189ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_bmnzi_b: 190ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_bmzi_b: i = 2; l = 0; u = 255; break; 191ed35a92cSVlad Serebrennikov // df/n format 192ed35a92cSVlad Serebrennikov // These intrinsics take an unsigned 4 bit immediate. 193ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_copy_s_b: 194ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_copy_u_b: 195ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_insve_b: 196ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_splati_b: i = 1; l = 0; u = 15; break; 197ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_sldi_b: i = 2; l = 0; u = 15; break; 198ed35a92cSVlad Serebrennikov // These intrinsics take an unsigned 3 bit immediate. 199ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_copy_s_h: 200ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_copy_u_h: 201ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_insve_h: 202ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_splati_h: i = 1; l = 0; u = 7; break; 203ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_sldi_h: i = 2; l = 0; u = 7; break; 204ed35a92cSVlad Serebrennikov // These intrinsics take an unsigned 2 bit immediate. 205ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_copy_s_w: 206ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_copy_u_w: 207ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_insve_w: 208ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_splati_w: i = 1; l = 0; u = 3; break; 209ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_sldi_w: i = 2; l = 0; u = 3; break; 210ed35a92cSVlad Serebrennikov // These intrinsics take an unsigned 1 bit immediate. 211ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_copy_s_d: 212ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_copy_u_d: 213ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_insve_d: 214ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_splati_d: i = 1; l = 0; u = 1; break; 215ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_sldi_d: i = 2; l = 0; u = 1; break; 216ed35a92cSVlad Serebrennikov // Memory offsets and immediate loads. 217ed35a92cSVlad Serebrennikov // These intrinsics take a signed 10 bit immediate. 218ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_ldi_b: i = 0; l = -128; u = 255; break; 219ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_ldi_h: 220ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_ldi_w: 221ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_ldi_d: i = 0; l = -512; u = 511; break; 222ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_ld_b: i = 1; l = -512; u = 511; m = 1; break; 223ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_ld_h: i = 1; l = -1024; u = 1022; m = 2; break; 224ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_ld_w: i = 1; l = -2048; u = 2044; m = 4; break; 225ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_ld_d: i = 1; l = -4096; u = 4088; m = 8; break; 226ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_ldr_d: i = 1; l = -4096; u = 4088; m = 8; break; 227ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_ldr_w: i = 1; l = -2048; u = 2044; m = 4; break; 228ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_st_b: i = 2; l = -512; u = 511; m = 1; break; 229ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_st_h: i = 2; l = -1024; u = 1022; m = 2; break; 230ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_st_w: i = 2; l = -2048; u = 2044; m = 4; break; 231ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_st_d: i = 2; l = -4096; u = 4088; m = 8; break; 232ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_str_d: i = 2; l = -4096; u = 4088; m = 8; break; 233ed35a92cSVlad Serebrennikov case Mips::BI__builtin_msa_str_w: i = 2; l = -2048; u = 2044; m = 4; break; 234ed35a92cSVlad Serebrennikov } 235ed35a92cSVlad Serebrennikov 236ed35a92cSVlad Serebrennikov if (!m) 237ed35a92cSVlad Serebrennikov return SemaRef.BuiltinConstantArgRange(TheCall, i, l, u); 238ed35a92cSVlad Serebrennikov 239ed35a92cSVlad Serebrennikov return SemaRef.BuiltinConstantArgRange(TheCall, i, l, u) || 240ed35a92cSVlad Serebrennikov SemaRef.BuiltinConstantArgMultiple(TheCall, i, m); 241ed35a92cSVlad Serebrennikov } 242ed35a92cSVlad Serebrennikov 2436b755b0cSVlad Serebrennikov void SemaMIPS::handleInterruptAttr(Decl *D, const ParsedAttr &AL) { 2446b755b0cSVlad Serebrennikov // Only one optional argument permitted. 2456b755b0cSVlad Serebrennikov if (AL.getNumArgs() > 1) { 2466b755b0cSVlad Serebrennikov Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << AL << 1; 2476b755b0cSVlad Serebrennikov return; 2486b755b0cSVlad Serebrennikov } 2496b755b0cSVlad Serebrennikov 2506b755b0cSVlad Serebrennikov StringRef Str; 2516b755b0cSVlad Serebrennikov SourceLocation ArgLoc; 2526b755b0cSVlad Serebrennikov 2536b755b0cSVlad Serebrennikov if (AL.getNumArgs() == 0) 2546b755b0cSVlad Serebrennikov Str = ""; 2556b755b0cSVlad Serebrennikov else if (!SemaRef.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc)) 2566b755b0cSVlad Serebrennikov return; 2576b755b0cSVlad Serebrennikov 2586b755b0cSVlad Serebrennikov // Semantic checks for a function with the 'interrupt' attribute for MIPS: 2596b755b0cSVlad Serebrennikov // a) Must be a function. 2606b755b0cSVlad Serebrennikov // b) Must have no parameters. 2616b755b0cSVlad Serebrennikov // c) Must have the 'void' return type. 2626b755b0cSVlad Serebrennikov // d) Cannot have the 'mips16' attribute, as that instruction set 2636b755b0cSVlad Serebrennikov // lacks the 'eret' instruction. 2646b755b0cSVlad Serebrennikov // e) The attribute itself must either have no argument or one of the 2656b755b0cSVlad Serebrennikov // valid interrupt types, see [MipsInterruptDocs]. 2666b755b0cSVlad Serebrennikov 2676b755b0cSVlad Serebrennikov if (!isFuncOrMethodForAttrSubject(D)) { 2686b755b0cSVlad Serebrennikov Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) 2696b755b0cSVlad Serebrennikov << AL << AL.isRegularKeywordAttribute() << ExpectedFunctionOrMethod; 2706b755b0cSVlad Serebrennikov return; 2716b755b0cSVlad Serebrennikov } 2726b755b0cSVlad Serebrennikov 2736b755b0cSVlad Serebrennikov if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) { 2746b755b0cSVlad Serebrennikov Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid) 2756b755b0cSVlad Serebrennikov << /*MIPS*/ 0 << 0; 2766b755b0cSVlad Serebrennikov return; 2776b755b0cSVlad Serebrennikov } 2786b755b0cSVlad Serebrennikov 2796b755b0cSVlad Serebrennikov if (!getFunctionOrMethodResultType(D)->isVoidType()) { 2806b755b0cSVlad Serebrennikov Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid) 2816b755b0cSVlad Serebrennikov << /*MIPS*/ 0 << 1; 2826b755b0cSVlad Serebrennikov return; 2836b755b0cSVlad Serebrennikov } 2846b755b0cSVlad Serebrennikov 2856b755b0cSVlad Serebrennikov // We still have to do this manually because the Interrupt attributes are 2866b755b0cSVlad Serebrennikov // a bit special due to sharing their spellings across targets. 2876b755b0cSVlad Serebrennikov if (checkAttrMutualExclusion<Mips16Attr>(*this, D, AL)) 2886b755b0cSVlad Serebrennikov return; 2896b755b0cSVlad Serebrennikov 2906b755b0cSVlad Serebrennikov MipsInterruptAttr::InterruptType Kind; 2916b755b0cSVlad Serebrennikov if (!MipsInterruptAttr::ConvertStrToInterruptType(Str, Kind)) { 2926b755b0cSVlad Serebrennikov Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) 2936b755b0cSVlad Serebrennikov << AL << "'" + std::string(Str) + "'"; 2946b755b0cSVlad Serebrennikov return; 2956b755b0cSVlad Serebrennikov } 2966b755b0cSVlad Serebrennikov 2976b755b0cSVlad Serebrennikov D->addAttr(::new (getASTContext()) 2986b755b0cSVlad Serebrennikov MipsInterruptAttr(getASTContext(), AL, Kind)); 2996b755b0cSVlad Serebrennikov } 3006b755b0cSVlad Serebrennikov 301ed35a92cSVlad Serebrennikov } // namespace clang 302