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