xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===-- XtensaMCTargetDesc.cpp - Xtensa target descriptions ---------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
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-exception
8 //
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_DESC
25 #include "XtensaGenInstrInfo.inc"
26 
27 #define GET_REGINFO_MC_DESC
28 #include "XtensaGenRegisterInfo.inc"
29 
30 #define GET_SUBTARGETINFO_MC_DESC
31 #include "XtensaGenSubtargetInfo.inc"
32 
33 using namespace llvm;
34 
isValidAddrOffset(int Scale,int64_t OffsetVal)35 bool 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 
isValidAddrOffsetForOpcode(unsigned Opcode,int64_t Offset)54 bool 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 operation
71     Scale = 4;
72     break;
73   }
74   return isValidAddrOffset(Scale, Offset);
75 }
76 
77 // Verify Special Register
checkRegister(MCRegister RegNo,const FeatureBitset & FeatureBits,RegisterAccessType RAType)78 bool 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     LLVM_FALLTHROUGH;
88   case Xtensa::CCOMPARE1:
89     if (FeatureBits[Xtensa::FeatureTimers2])
90       return true;
91     LLVM_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     LLVM_FALLTHROUGH;
111   case Xtensa::EPC2:
112   case Xtensa::EPS2:
113   case Xtensa::EXCSAVE2:
114     if (FeatureBits[Xtensa::FeatureHighPriInterrupts])
115       return true;
116     LLVM_FALLTHROUGH;
117   case Xtensa::EPC3:
118   case Xtensa::EPS3:
119   case Xtensa::EXCSAVE3:
120     if (FeatureBits[Xtensa::FeatureHighPriInterruptsLevel3])
121       return true;
122     LLVM_FALLTHROUGH;
123   case Xtensa::EPC4:
124   case Xtensa::EPS4:
125   case Xtensa::EXCSAVE4:
126     if (FeatureBits[Xtensa::FeatureHighPriInterruptsLevel4])
127       return true;
128     LLVM_FALLTHROUGH;
129   case Xtensa::EPC5:
130   case Xtensa::EPS5:
131   case Xtensa::EXCSAVE5:
132     if (FeatureBits[Xtensa::FeatureHighPriInterruptsLevel5])
133       return true;
134     LLVM_FALLTHROUGH;
135   case Xtensa::EPC6:
136   case Xtensa::EPS6:
137   case Xtensa::EXCSAVE6:
138     if (FeatureBits[Xtensa::FeatureHighPriInterruptsLevel6])
139       return true;
140     LLVM_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::NoRegister:
204     return false;
205   }
206 
207   return true;
208 }
209 
210 // Get Xtensa User Register by encoding value.
getUserRegister(unsigned Code,const MCRegisterInfo & MRI)211 MCRegister Xtensa::getUserRegister(unsigned Code, const MCRegisterInfo &MRI) {
212   MCRegister UserReg = Xtensa::NoRegister;
213 
214   if (MRI.getEncodingValue(Xtensa::FCR) == Code) {
215     UserReg = Xtensa::FCR;
216   } else if (MRI.getEncodingValue(Xtensa::FSR) == Code) {
217     UserReg = Xtensa::FSR;
218   } else if (MRI.getEncodingValue(Xtensa::F64R_LO) == Code) {
219     UserReg = Xtensa::F64R_LO;
220   } else if (MRI.getEncodingValue(Xtensa::F64R_HI) == Code) {
221     UserReg = Xtensa::F64R_HI;
222   } else if (MRI.getEncodingValue(Xtensa::F64S) == Code) {
223     UserReg = Xtensa::F64S;
224   } else if (MRI.getEncodingValue(Xtensa::THREADPTR) == Code) {
225     UserReg = Xtensa::THREADPTR;
226   }
227 
228   return UserReg;
229 }
230 
createXtensaMCAsmInfo(const MCRegisterInfo & MRI,const Triple & TT,const MCTargetOptions & Options)231 static MCAsmInfo *createXtensaMCAsmInfo(const MCRegisterInfo &MRI,
232                                         const Triple &TT,
233                                         const MCTargetOptions &Options) {
234   MCAsmInfo *MAI = new XtensaMCAsmInfo(TT);
235   return MAI;
236 }
237 
createXtensaMCInstrInfo()238 static MCInstrInfo *createXtensaMCInstrInfo() {
239   MCInstrInfo *X = new MCInstrInfo();
240   InitXtensaMCInstrInfo(X);
241   return X;
242 }
243 
createXtensaMCInstPrinter(const Triple & TT,unsigned SyntaxVariant,const MCAsmInfo & MAI,const MCInstrInfo & MII,const MCRegisterInfo & MRI)244 static MCInstPrinter *createXtensaMCInstPrinter(const Triple &TT,
245                                                 unsigned SyntaxVariant,
246                                                 const MCAsmInfo &MAI,
247                                                 const MCInstrInfo &MII,
248                                                 const MCRegisterInfo &MRI) {
249   return new XtensaInstPrinter(MAI, MII, MRI);
250 }
251 
createXtensaMCRegisterInfo(const Triple & TT)252 static MCRegisterInfo *createXtensaMCRegisterInfo(const Triple &TT) {
253   MCRegisterInfo *X = new MCRegisterInfo();
254   InitXtensaMCRegisterInfo(X, Xtensa::SP);
255   return X;
256 }
257 
258 static MCSubtargetInfo *
createXtensaMCSubtargetInfo(const Triple & TT,StringRef CPU,StringRef FS)259 createXtensaMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
260   return createXtensaMCSubtargetInfoImpl(TT, CPU, CPU, FS);
261 }
262 
263 static MCTargetStreamer *
createXtensaAsmTargetStreamer(MCStreamer & S,formatted_raw_ostream & OS,MCInstPrinter * InstPrint)264 createXtensaAsmTargetStreamer(MCStreamer &S, formatted_raw_ostream &OS,
265                               MCInstPrinter *InstPrint) {
266   return new XtensaTargetAsmStreamer(S, OS);
267 }
268 
269 static MCTargetStreamer *
createXtensaObjectTargetStreamer(MCStreamer & S,const MCSubtargetInfo & STI)270 createXtensaObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
271   return new XtensaTargetELFStreamer(S);
272 }
273 
LLVMInitializeXtensaTargetMC()274 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaTargetMC() {
275   // Register the MCAsmInfo.
276   TargetRegistry::RegisterMCAsmInfo(getTheXtensaTarget(),
277                                     createXtensaMCAsmInfo);
278 
279   // Register the MCCodeEmitter.
280   TargetRegistry::RegisterMCCodeEmitter(getTheXtensaTarget(),
281                                         createXtensaMCCodeEmitter);
282 
283   // Register the MCInstrInfo.
284   TargetRegistry::RegisterMCInstrInfo(getTheXtensaTarget(),
285                                       createXtensaMCInstrInfo);
286 
287   // Register the MCInstPrinter.
288   TargetRegistry::RegisterMCInstPrinter(getTheXtensaTarget(),
289                                         createXtensaMCInstPrinter);
290 
291   // Register the MCRegisterInfo.
292   TargetRegistry::RegisterMCRegInfo(getTheXtensaTarget(),
293                                     createXtensaMCRegisterInfo);
294 
295   // Register the MCSubtargetInfo.
296   TargetRegistry::RegisterMCSubtargetInfo(getTheXtensaTarget(),
297                                           createXtensaMCSubtargetInfo);
298 
299   // Register the MCAsmBackend.
300   TargetRegistry::RegisterMCAsmBackend(getTheXtensaTarget(),
301                                        createXtensaAsmBackend);
302 
303   // Register the asm target streamer.
304   TargetRegistry::RegisterAsmTargetStreamer(getTheXtensaTarget(),
305                                             createXtensaAsmTargetStreamer);
306 
307   // Register the ELF target streamer.
308   TargetRegistry::RegisterObjectTargetStreamer(
309       getTheXtensaTarget(), createXtensaObjectTargetStreamer);
310 }
311