314 lines · cpp
1//===-- XtensaMCTargetDesc.cpp - Xtensa target descriptions ---------------===//2//3// The LLVM Compiler Infrastructure4//5// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.6// See https://llvm.org/LICENSE.txt for license information.7// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception8//9//===----------------------------------------------------------------------===//10#include "XtensaMCTargetDesc.h"11#include "TargetInfo/XtensaTargetInfo.h"12#include "XtensaInstPrinter.h"13#include "XtensaMCAsmInfo.h"14#include "XtensaTargetStreamer.h"15#include "llvm/ADT/STLExtras.h"16#include "llvm/MC/MCAsmInfo.h"17#include "llvm/MC/MCInstrInfo.h"18#include "llvm/MC/MCRegisterInfo.h"19#include "llvm/MC/MCStreamer.h"20#include "llvm/MC/MCSubtargetInfo.h"21#include "llvm/MC/TargetRegistry.h"22#include "llvm/Support/ErrorHandling.h"23 24#define GET_INSTRINFO_MC_DESC25#include "XtensaGenInstrInfo.inc"26 27#define GET_REGINFO_MC_DESC28#include "XtensaGenRegisterInfo.inc"29 30#define GET_SUBTARGETINFO_MC_DESC31#include "XtensaGenSubtargetInfo.inc"32 33using namespace llvm;34 35bool Xtensa::isValidAddrOffset(int Scale, int64_t OffsetVal) {36 bool Valid = false;37 38 switch (Scale) {39 case 1:40 Valid = (OffsetVal >= 0 && OffsetVal <= 255);41 break;42 case 2:43 Valid = (OffsetVal >= 0 && OffsetVal <= 510) && ((OffsetVal & 0x1) == 0);44 break;45 case 4:46 Valid = (OffsetVal >= 0 && OffsetVal <= 1020) && ((OffsetVal & 0x3) == 0);47 break;48 default:49 break;50 }51 return Valid;52}53 54bool Xtensa::isValidAddrOffsetForOpcode(unsigned Opcode, int64_t Offset) {55 int Scale = 0;56 57 switch (Opcode) {58 case Xtensa::L8UI:59 case Xtensa::S8I:60 Scale = 1;61 break;62 case Xtensa::L16SI:63 case Xtensa::L16UI:64 case Xtensa::S16I:65 Scale = 2;66 break;67 case Xtensa::LEA_ADD:68 return (Offset >= -128 && Offset <= 127);69 default:70 // assume that MI is 32-bit load/store operation71 Scale = 4;72 break;73 }74 return isValidAddrOffset(Scale, Offset);75}76 77// Verify Special Register78bool Xtensa::checkRegister(MCRegister RegNo, const FeatureBitset &FeatureBits,79 RegisterAccessType RAType) {80 switch (RegNo) {81 case Xtensa::BREG:82 return FeatureBits[Xtensa::FeatureBoolean];83 case Xtensa::CCOUNT:84 case Xtensa::CCOMPARE0:85 if (FeatureBits[Xtensa::FeatureTimers1])86 return true;87 [[fallthrough]];88 case Xtensa::CCOMPARE1:89 if (FeatureBits[Xtensa::FeatureTimers2])90 return true;91 [[fallthrough]];92 case Xtensa::CCOMPARE2:93 if (FeatureBits[Xtensa::FeatureTimers3])94 return true;95 return false;96 case Xtensa::CONFIGID0:97 return RAType != Xtensa::REGISTER_EXCHANGE;98 case Xtensa::CONFIGID1:99 return RAType == Xtensa::REGISTER_READ;100 case Xtensa::CPENABLE:101 return FeatureBits[Xtensa::FeatureCoprocessor];102 case Xtensa::DEBUGCAUSE:103 return RAType == Xtensa::REGISTER_READ && FeatureBits[Xtensa::FeatureDebug];104 case Xtensa::DEPC:105 case Xtensa::EPC1:106 case Xtensa::EXCCAUSE:107 case Xtensa::EXCSAVE1:108 case Xtensa::EXCVADDR:109 return FeatureBits[Xtensa::FeatureException];110 [[fallthrough]];111 case Xtensa::EPC2:112 case Xtensa::EPS2:113 case Xtensa::EXCSAVE2:114 if (FeatureBits[Xtensa::FeatureHighPriInterrupts])115 return true;116 [[fallthrough]];117 case Xtensa::EPC3:118 case Xtensa::EPS3:119 case Xtensa::EXCSAVE3:120 if (FeatureBits[Xtensa::FeatureHighPriInterruptsLevel3])121 return true;122 [[fallthrough]];123 case Xtensa::EPC4:124 case Xtensa::EPS4:125 case Xtensa::EXCSAVE4:126 if (FeatureBits[Xtensa::FeatureHighPriInterruptsLevel4])127 return true;128 [[fallthrough]];129 case Xtensa::EPC5:130 case Xtensa::EPS5:131 case Xtensa::EXCSAVE5:132 if (FeatureBits[Xtensa::FeatureHighPriInterruptsLevel5])133 return true;134 [[fallthrough]];135 case Xtensa::EPC6:136 case Xtensa::EPS6:137 case Xtensa::EXCSAVE6:138 if (FeatureBits[Xtensa::FeatureHighPriInterruptsLevel6])139 return true;140 [[fallthrough]];141 case Xtensa::EPC7:142 case Xtensa::EPS7:143 case Xtensa::EXCSAVE7:144 if (FeatureBits[Xtensa::FeatureHighPriInterruptsLevel7])145 return true;146 return false;147 case Xtensa::INTENABLE:148 return FeatureBits[Xtensa::FeatureInterrupt];149 case Xtensa::INTERRUPT:150 return RAType == Xtensa::REGISTER_READ &&151 FeatureBits[Xtensa::FeatureInterrupt];152 case Xtensa::INTSET:153 case Xtensa::INTCLEAR:154 return RAType == Xtensa::REGISTER_WRITE &&155 FeatureBits[Xtensa::FeatureInterrupt];156 case Xtensa::ICOUNT:157 case Xtensa::ICOUNTLEVEL:158 case Xtensa::IBREAKENABLE:159 case Xtensa::DDR:160 case Xtensa::IBREAKA0:161 case Xtensa::IBREAKA1:162 case Xtensa::DBREAKA0:163 case Xtensa::DBREAKA1:164 case Xtensa::DBREAKC0:165 case Xtensa::DBREAKC1:166 return FeatureBits[Xtensa::FeatureDebug];167 case Xtensa::LBEG:168 case Xtensa::LEND:169 case Xtensa::LCOUNT:170 return FeatureBits[Xtensa::FeatureLoop];171 case Xtensa::LITBASE:172 return FeatureBits[Xtensa::FeatureExtendedL32R];173 case Xtensa::MEMCTL:174 return FeatureBits[Xtensa::FeatureDataCache];175 case Xtensa::ACCLO:176 case Xtensa::ACCHI:177 case Xtensa::M0:178 case Xtensa::M1:179 case Xtensa::M2:180 case Xtensa::M3:181 return FeatureBits[Xtensa::FeatureMAC16];182 case Xtensa::MISC0:183 case Xtensa::MISC1:184 case Xtensa::MISC2:185 case Xtensa::MISC3:186 return FeatureBits[Xtensa::FeatureMiscSR];187 case Xtensa::PRID:188 return RAType == Xtensa::REGISTER_READ && FeatureBits[Xtensa::FeaturePRID];189 case Xtensa::THREADPTR:190 return FeatureBits[FeatureTHREADPTR];191 case Xtensa::VECBASE:192 return FeatureBits[Xtensa::FeatureRelocatableVector];193 case Xtensa::FCR:194 case Xtensa::FSR:195 return FeatureBits[FeatureSingleFloat];196 case Xtensa::F64R_LO:197 case Xtensa::F64R_HI:198 case Xtensa::F64S:199 return FeatureBits[FeatureDFPAccel];200 case Xtensa::WINDOWBASE:201 case Xtensa::WINDOWSTART:202 return FeatureBits[Xtensa::FeatureWindowed];203 case Xtensa::ATOMCTL:204 case Xtensa::SCOMPARE1:205 return FeatureBits[Xtensa::FeatureS32C1I];206 case Xtensa::NoRegister:207 return false;208 }209 210 return true;211}212 213// Get Xtensa User Register by encoding value.214MCRegister Xtensa::getUserRegister(unsigned Code, const MCRegisterInfo &MRI) {215 MCRegister UserReg = Xtensa::NoRegister;216 217 if (MRI.getEncodingValue(Xtensa::FCR) == Code) {218 UserReg = Xtensa::FCR;219 } else if (MRI.getEncodingValue(Xtensa::FSR) == Code) {220 UserReg = Xtensa::FSR;221 } else if (MRI.getEncodingValue(Xtensa::F64R_LO) == Code) {222 UserReg = Xtensa::F64R_LO;223 } else if (MRI.getEncodingValue(Xtensa::F64R_HI) == Code) {224 UserReg = Xtensa::F64R_HI;225 } else if (MRI.getEncodingValue(Xtensa::F64S) == Code) {226 UserReg = Xtensa::F64S;227 } else if (MRI.getEncodingValue(Xtensa::THREADPTR) == Code) {228 UserReg = Xtensa::THREADPTR;229 }230 231 return UserReg;232}233 234static MCAsmInfo *createXtensaMCAsmInfo(const MCRegisterInfo &MRI,235 const Triple &TT,236 const MCTargetOptions &Options) {237 MCAsmInfo *MAI = new XtensaMCAsmInfo(TT);238 return MAI;239}240 241static MCInstrInfo *createXtensaMCInstrInfo() {242 MCInstrInfo *X = new MCInstrInfo();243 InitXtensaMCInstrInfo(X);244 return X;245}246 247static MCInstPrinter *createXtensaMCInstPrinter(const Triple &TT,248 unsigned SyntaxVariant,249 const MCAsmInfo &MAI,250 const MCInstrInfo &MII,251 const MCRegisterInfo &MRI) {252 return new XtensaInstPrinter(MAI, MII, MRI);253}254 255static MCRegisterInfo *createXtensaMCRegisterInfo(const Triple &TT) {256 MCRegisterInfo *X = new MCRegisterInfo();257 InitXtensaMCRegisterInfo(X, Xtensa::SP);258 return X;259}260 261static MCSubtargetInfo *262createXtensaMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {263 return createXtensaMCSubtargetInfoImpl(TT, CPU, CPU, FS);264}265 266static MCTargetStreamer *267createXtensaAsmTargetStreamer(MCStreamer &S, formatted_raw_ostream &OS,268 MCInstPrinter *InstPrint) {269 return new XtensaTargetAsmStreamer(S, OS);270}271 272static MCTargetStreamer *273createXtensaObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {274 return new XtensaTargetELFStreamer(S);275}276 277extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaTargetMC() {278 // Register the MCAsmInfo.279 TargetRegistry::RegisterMCAsmInfo(getTheXtensaTarget(),280 createXtensaMCAsmInfo);281 282 // Register the MCCodeEmitter.283 TargetRegistry::RegisterMCCodeEmitter(getTheXtensaTarget(),284 createXtensaMCCodeEmitter);285 286 // Register the MCInstrInfo.287 TargetRegistry::RegisterMCInstrInfo(getTheXtensaTarget(),288 createXtensaMCInstrInfo);289 290 // Register the MCInstPrinter.291 TargetRegistry::RegisterMCInstPrinter(getTheXtensaTarget(),292 createXtensaMCInstPrinter);293 294 // Register the MCRegisterInfo.295 TargetRegistry::RegisterMCRegInfo(getTheXtensaTarget(),296 createXtensaMCRegisterInfo);297 298 // Register the MCSubtargetInfo.299 TargetRegistry::RegisterMCSubtargetInfo(getTheXtensaTarget(),300 createXtensaMCSubtargetInfo);301 302 // Register the MCAsmBackend.303 TargetRegistry::RegisterMCAsmBackend(getTheXtensaTarget(),304 createXtensaAsmBackend);305 306 // Register the asm target streamer.307 TargetRegistry::RegisterAsmTargetStreamer(getTheXtensaTarget(),308 createXtensaAsmTargetStreamer);309 310 // Register the ELF target streamer.311 TargetRegistry::RegisterObjectTargetStreamer(312 getTheXtensaTarget(), createXtensaObjectTargetStreamer);313}314