LLVM 20.0.0git
SparcAsmParser.cpp
Go to the documentation of this file.
1//===-- SparcAsmParser.cpp - Parse Sparc assembly to MCInst instructions --===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
13#include "llvm/ADT/StringRef.h"
14#include "llvm/MC/MCAsmMacro.h"
15#include "llvm/MC/MCContext.h"
16#include "llvm/MC/MCExpr.h"
17#include "llvm/MC/MCInst.h"
19#include "llvm/MC/MCInstrInfo.h"
26#include "llvm/MC/MCStreamer.h"
28#include "llvm/MC/MCSymbol.h"
33#include "llvm/Support/SMLoc.h"
36#include <algorithm>
37#include <cassert>
38#include <cstdint>
39#include <memory>
40
41using namespace llvm;
42
43// The generated AsmMatcher SparcGenAsmMatcher uses "Sparc" as the target
44// namespace. But SPARC backend uses "SP" as its namespace.
45namespace llvm {
46namespace Sparc {
47
48 using namespace SP;
49
50} // end namespace Sparc
51} // end namespace llvm
52
53namespace {
54
55class SparcOperand;
56
57class SparcAsmParser : public MCTargetAsmParser {
58 MCAsmParser &Parser;
59 const MCRegisterInfo &MRI;
60
61 enum class TailRelocKind { Load_GOT, Add_TLS, Load_TLS, Call_TLS };
62
63 /// @name Auto-generated Match Functions
64 /// {
65
66#define GET_ASSEMBLER_HEADER
67#include "SparcGenAsmMatcher.inc"
68
69 /// }
70
71 // public interface of the MCTargetAsmParser.
72 bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
75 bool MatchingInlineAsm) override;
76 bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
78 SMLoc &EndLoc) override;
80 SMLoc NameLoc, OperandVector &Operands) override;
81 ParseStatus parseDirective(AsmToken DirectiveID) override;
82
84 unsigned Kind) override;
85
86 // Custom parse functions for Sparc specific operands.
87 ParseStatus parseMEMOperand(OperandVector &Operands);
88
89 ParseStatus parseMembarTag(OperandVector &Operands);
90
92
93 ParseStatus parsePrefetchTag(OperandVector &Operands);
94
95 template <TailRelocKind Kind>
96 ParseStatus parseTailRelocSym(OperandVector &Operands);
97
98 template <unsigned N> ParseStatus parseShiftAmtImm(OperandVector &Operands);
99
100 ParseStatus parseCallTarget(OperandVector &Operands);
101
103
104 ParseStatus parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Operand,
105 bool isCall = false);
106
107 ParseStatus parseBranchModifiers(OperandVector &Operands);
108
109 ParseStatus parseExpression(int64_t &Val);
110
111 // Helper function for dealing with %lo / %hi in PIC mode.
112 const SparcMCExpr *adjustPICRelocation(SparcMCExpr::VariantKind VK,
113 const MCExpr *subExpr);
114
115 // Helper function to see if current token can start an expression.
116 bool isPossibleExpression(const AsmToken &Token);
117
118 // Check if mnemonic is valid.
119 MatchResultTy mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);
120
121 // returns true if Tok is matched to a register and returns register in RegNo.
122 MCRegister matchRegisterName(const AsmToken &Tok, unsigned &RegKind);
123
124 bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc);
125
126 bool is64Bit() const {
128 }
129
130 bool expandSET(MCInst &Inst, SMLoc IDLoc,
131 SmallVectorImpl<MCInst> &Instructions);
132
133 bool expandSETX(MCInst &Inst, SMLoc IDLoc,
134 SmallVectorImpl<MCInst> &Instructions);
135
136 SMLoc getLoc() const { return getParser().getTok().getLoc(); }
137
138public:
139 SparcAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
140 const MCInstrInfo &MII, const MCTargetOptions &Options)
141 : MCTargetAsmParser(Options, sti, MII), Parser(parser),
142 MRI(*Parser.getContext().getRegisterInfo()) {
143 Parser.addAliasForDirective(".half", ".2byte");
144 Parser.addAliasForDirective(".uahalf", ".2byte");
145 Parser.addAliasForDirective(".word", ".4byte");
146 Parser.addAliasForDirective(".uaword", ".4byte");
147 Parser.addAliasForDirective(".nword", is64Bit() ? ".8byte" : ".4byte");
148 if (is64Bit())
149 Parser.addAliasForDirective(".xword", ".8byte");
150
151 // Initialize the set of available features.
152 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
153 }
154};
155
156} // end anonymous namespace
157
158 static const MCPhysReg IntRegs[32] = {
159 Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,
160 Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,
161 Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,
162 Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,
163 Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,
164 Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,
165 Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,
166 Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };
167
168 static const MCPhysReg DoubleRegs[32] = {
169 Sparc::D0, Sparc::D1, Sparc::D2, Sparc::D3,
170 Sparc::D4, Sparc::D5, Sparc::D6, Sparc::D7,
171 Sparc::D8, Sparc::D9, Sparc::D10, Sparc::D11,
172 Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,
173 Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,
174 Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,
175 Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,
176 Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };
177
178 static const MCPhysReg QuadFPRegs[32] = {
179 Sparc::Q0, Sparc::Q1, Sparc::Q2, Sparc::Q3,
180 Sparc::Q4, Sparc::Q5, Sparc::Q6, Sparc::Q7,
181 Sparc::Q8, Sparc::Q9, Sparc::Q10, Sparc::Q11,
182 Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
183
184 static const MCPhysReg IntPairRegs[] = {
185 Sparc::G0_G1, Sparc::G2_G3, Sparc::G4_G5, Sparc::G6_G7,
186 Sparc::O0_O1, Sparc::O2_O3, Sparc::O4_O5, Sparc::O6_O7,
187 Sparc::L0_L1, Sparc::L2_L3, Sparc::L4_L5, Sparc::L6_L7,
188 Sparc::I0_I1, Sparc::I2_I3, Sparc::I4_I5, Sparc::I6_I7};
189
190 static const MCPhysReg CoprocPairRegs[] = {
191 Sparc::C0_C1, Sparc::C2_C3, Sparc::C4_C5, Sparc::C6_C7,
192 Sparc::C8_C9, Sparc::C10_C11, Sparc::C12_C13, Sparc::C14_C15,
193 Sparc::C16_C17, Sparc::C18_C19, Sparc::C20_C21, Sparc::C22_C23,
194 Sparc::C24_C25, Sparc::C26_C27, Sparc::C28_C29, Sparc::C30_C31};
195
196namespace {
197
198/// SparcOperand - Instances of this class represent a parsed Sparc machine
199/// instruction.
200class SparcOperand : public MCParsedAsmOperand {
201public:
202 enum RegisterKind {
203 rk_None,
204 rk_IntReg,
205 rk_IntPairReg,
206 rk_FloatReg,
207 rk_DoubleReg,
208 rk_QuadReg,
209 rk_CoprocReg,
210 rk_CoprocPairReg,
211 rk_Special,
212 };
213
214private:
215 enum KindTy {
216 k_Token,
217 k_Register,
218 k_Immediate,
219 k_MemoryReg,
220 k_MemoryImm,
221 k_ASITag,
222 k_PrefetchTag,
223 k_TailRelocSym, // Special kind of immediate for TLS relocation purposes.
224 } Kind;
225
226 SMLoc StartLoc, EndLoc;
227
228 struct Token {
229 const char *Data;
230 unsigned Length;
231 };
232
233 struct RegOp {
234 unsigned RegNum;
235 RegisterKind Kind;
236 };
237
238 struct ImmOp {
239 const MCExpr *Val;
240 };
241
242 struct MemOp {
243 unsigned Base;
244 unsigned OffsetReg;
245 const MCExpr *Off;
246 };
247
248 union {
249 struct Token Tok;
250 struct RegOp Reg;
251 struct ImmOp Imm;
252 struct MemOp Mem;
253 unsigned ASI;
254 unsigned Prefetch;
255 };
256
257public:
258 SparcOperand(KindTy K) : Kind(K) {}
259
260 bool isToken() const override { return Kind == k_Token; }
261 bool isReg() const override { return Kind == k_Register; }
262 bool isImm() const override { return Kind == k_Immediate; }
263 bool isMem() const override { return isMEMrr() || isMEMri(); }
264 bool isMEMrr() const { return Kind == k_MemoryReg; }
265 bool isMEMri() const { return Kind == k_MemoryImm; }
266 bool isMembarTag() const { return Kind == k_Immediate; }
267 bool isASITag() const { return Kind == k_ASITag; }
268 bool isPrefetchTag() const { return Kind == k_PrefetchTag; }
269 bool isTailRelocSym() const { return Kind == k_TailRelocSym; }
270
271 bool isCallTarget() const {
272 if (!isImm())
273 return false;
274
275 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val))
276 return CE->getValue() % 4 == 0;
277
278 return true;
279 }
280
281 bool isShiftAmtImm5() const {
282 if (!isImm())
283 return false;
284
285 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val))
286 return isUInt<5>(CE->getValue());
287
288 return false;
289 }
290
291 bool isShiftAmtImm6() const {
292 if (!isImm())
293 return false;
294
295 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val))
296 return isUInt<6>(CE->getValue());
297
298 return false;
299 }
300
301 bool isIntReg() const {
302 return (Kind == k_Register && Reg.Kind == rk_IntReg);
303 }
304
305 bool isFloatReg() const {
306 return (Kind == k_Register && Reg.Kind == rk_FloatReg);
307 }
308
309 bool isFloatOrDoubleReg() const {
310 return (Kind == k_Register && (Reg.Kind == rk_FloatReg
311 || Reg.Kind == rk_DoubleReg));
312 }
313
314 bool isCoprocReg() const {
315 return (Kind == k_Register && Reg.Kind == rk_CoprocReg);
316 }
317
318 StringRef getToken() const {
319 assert(Kind == k_Token && "Invalid access!");
320 return StringRef(Tok.Data, Tok.Length);
321 }
322
323 MCRegister getReg() const override {
324 assert((Kind == k_Register) && "Invalid access!");
325 return Reg.RegNum;
326 }
327
328 const MCExpr *getImm() const {
329 assert((Kind == k_Immediate) && "Invalid access!");
330 return Imm.Val;
331 }
332
333 unsigned getMemBase() const {
334 assert((Kind == k_MemoryReg || Kind == k_MemoryImm) && "Invalid access!");
335 return Mem.Base;
336 }
337
338 unsigned getMemOffsetReg() const {
339 assert((Kind == k_MemoryReg) && "Invalid access!");
340 return Mem.OffsetReg;
341 }
342
343 const MCExpr *getMemOff() const {
344 assert((Kind == k_MemoryImm) && "Invalid access!");
345 return Mem.Off;
346 }
347
348 unsigned getASITag() const {
349 assert((Kind == k_ASITag) && "Invalid access!");
350 return ASI;
351 }
352
353 unsigned getPrefetchTag() const {
354 assert((Kind == k_PrefetchTag) && "Invalid access!");
355 return Prefetch;
356 }
357
358 const MCExpr *getTailRelocSym() const {
359 assert((Kind == k_TailRelocSym) && "Invalid access!");
360 return Imm.Val;
361 }
362
363 /// getStartLoc - Get the location of the first token of this operand.
364 SMLoc getStartLoc() const override {
365 return StartLoc;
366 }
367 /// getEndLoc - Get the location of the last token of this operand.
368 SMLoc getEndLoc() const override {
369 return EndLoc;
370 }
371
372 void print(raw_ostream &OS) const override {
373 switch (Kind) {
374 case k_Token: OS << "Token: " << getToken() << "\n"; break;
375 case k_Register: OS << "Reg: #" << getReg() << "\n"; break;
376 case k_Immediate: OS << "Imm: " << getImm() << "\n"; break;
377 case k_MemoryReg: OS << "Mem: " << getMemBase() << "+"
378 << getMemOffsetReg() << "\n"; break;
379 case k_MemoryImm: assert(getMemOff() != nullptr);
380 OS << "Mem: " << getMemBase()
381 << "+" << *getMemOff()
382 << "\n"; break;
383 case k_ASITag:
384 OS << "ASI tag: " << getASITag() << "\n";
385 break;
386 case k_PrefetchTag:
387 OS << "Prefetch tag: " << getPrefetchTag() << "\n";
388 break;
389 case k_TailRelocSym:
390 OS << "TailReloc: " << getTailRelocSym() << "\n";
391 break;
392 }
393 }
394
395 void addRegOperands(MCInst &Inst, unsigned N) const {
396 assert(N == 1 && "Invalid number of operands!");
398 }
399
400 void addImmOperands(MCInst &Inst, unsigned N) const {
401 assert(N == 1 && "Invalid number of operands!");
402 const MCExpr *Expr = getImm();
403 addExpr(Inst, Expr);
404 }
405
406 void addShiftAmtImm5Operands(MCInst &Inst, unsigned N) const {
407 assert(N == 1 && "Invalid number of operands!");
408 addExpr(Inst, getImm());
409 }
410 void addShiftAmtImm6Operands(MCInst &Inst, unsigned N) const {
411 assert(N == 1 && "Invalid number of operands!");
412 addExpr(Inst, getImm());
413 }
414
415 void addExpr(MCInst &Inst, const MCExpr *Expr) const{
416 // Add as immediate when possible. Null MCExpr = 0.
417 if (!Expr)
419 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
420 Inst.addOperand(MCOperand::createImm(CE->getValue()));
421 else
423 }
424
425 void addMEMrrOperands(MCInst &Inst, unsigned N) const {
426 assert(N == 2 && "Invalid number of operands!");
427
428 Inst.addOperand(MCOperand::createReg(getMemBase()));
429
430 assert(getMemOffsetReg() != 0 && "Invalid offset");
431 Inst.addOperand(MCOperand::createReg(getMemOffsetReg()));
432 }
433
434 void addMEMriOperands(MCInst &Inst, unsigned N) const {
435 assert(N == 2 && "Invalid number of operands!");
436
437 Inst.addOperand(MCOperand::createReg(getMemBase()));
438
439 const MCExpr *Expr = getMemOff();
440 addExpr(Inst, Expr);
441 }
442
443 void addASITagOperands(MCInst &Inst, unsigned N) const {
444 assert(N == 1 && "Invalid number of operands!");
445 Inst.addOperand(MCOperand::createImm(getASITag()));
446 }
447
448 void addPrefetchTagOperands(MCInst &Inst, unsigned N) const {
449 assert(N == 1 && "Invalid number of operands!");
450 Inst.addOperand(MCOperand::createImm(getPrefetchTag()));
451 }
452
453 void addMembarTagOperands(MCInst &Inst, unsigned N) const {
454 assert(N == 1 && "Invalid number of operands!");
455 const MCExpr *Expr = getImm();
456 addExpr(Inst, Expr);
457 }
458
459 void addCallTargetOperands(MCInst &Inst, unsigned N) const {
460 assert(N == 1 && "Invalid number of operands!");
461 addExpr(Inst, getImm());
462 }
463
464 void addTailRelocSymOperands(MCInst &Inst, unsigned N) const {
465 assert(N == 1 && "Invalid number of operands!");
466 addExpr(Inst, getTailRelocSym());
467 }
468
469 static std::unique_ptr<SparcOperand> CreateToken(StringRef Str, SMLoc S) {
470 auto Op = std::make_unique<SparcOperand>(k_Token);
471 Op->Tok.Data = Str.data();
472 Op->Tok.Length = Str.size();
473 Op->StartLoc = S;
474 Op->EndLoc = S;
475 return Op;
476 }
477
478 static std::unique_ptr<SparcOperand> CreateReg(unsigned RegNum, unsigned Kind,
479 SMLoc S, SMLoc E) {
480 auto Op = std::make_unique<SparcOperand>(k_Register);
481 Op->Reg.RegNum = RegNum;
482 Op->Reg.Kind = (SparcOperand::RegisterKind)Kind;
483 Op->StartLoc = S;
484 Op->EndLoc = E;
485 return Op;
486 }
487
488 static std::unique_ptr<SparcOperand> CreateImm(const MCExpr *Val, SMLoc S,
489 SMLoc E) {
490 auto Op = std::make_unique<SparcOperand>(k_Immediate);
491 Op->Imm.Val = Val;
492 Op->StartLoc = S;
493 Op->EndLoc = E;
494 return Op;
495 }
496
497 static std::unique_ptr<SparcOperand> CreateASITag(unsigned Val, SMLoc S,
498 SMLoc E) {
499 auto Op = std::make_unique<SparcOperand>(k_ASITag);
500 Op->ASI = Val;
501 Op->StartLoc = S;
502 Op->EndLoc = E;
503 return Op;
504 }
505
506 static std::unique_ptr<SparcOperand> CreatePrefetchTag(unsigned Val, SMLoc S,
507 SMLoc E) {
508 auto Op = std::make_unique<SparcOperand>(k_PrefetchTag);
509 Op->Prefetch = Val;
510 Op->StartLoc = S;
511 Op->EndLoc = E;
512 return Op;
513 }
514
515 static std::unique_ptr<SparcOperand> CreateTailRelocSym(const MCExpr *Val,
516 SMLoc S, SMLoc E) {
517 auto Op = std::make_unique<SparcOperand>(k_TailRelocSym);
518 Op->Imm.Val = Val;
519 Op->StartLoc = S;
520 Op->EndLoc = E;
521 return Op;
522 }
523
524 static bool MorphToIntPairReg(SparcOperand &Op) {
525 unsigned Reg = Op.getReg();
526 assert(Op.Reg.Kind == rk_IntReg);
527 unsigned regIdx = 32;
528 if (Reg >= Sparc::G0 && Reg <= Sparc::G7)
529 regIdx = Reg - Sparc::G0;
530 else if (Reg >= Sparc::O0 && Reg <= Sparc::O7)
531 regIdx = Reg - Sparc::O0 + 8;
532 else if (Reg >= Sparc::L0 && Reg <= Sparc::L7)
533 regIdx = Reg - Sparc::L0 + 16;
534 else if (Reg >= Sparc::I0 && Reg <= Sparc::I7)
535 regIdx = Reg - Sparc::I0 + 24;
536 if (regIdx % 2 || regIdx > 31)
537 return false;
538 Op.Reg.RegNum = IntPairRegs[regIdx / 2];
539 Op.Reg.Kind = rk_IntPairReg;
540 return true;
541 }
542
543 static bool MorphToDoubleReg(SparcOperand &Op) {
544 unsigned Reg = Op.getReg();
545 assert(Op.Reg.Kind == rk_FloatReg);
546 unsigned regIdx = Reg - Sparc::F0;
547 if (regIdx % 2 || regIdx > 31)
548 return false;
549 Op.Reg.RegNum = DoubleRegs[regIdx / 2];
550 Op.Reg.Kind = rk_DoubleReg;
551 return true;
552 }
553
554 static bool MorphToQuadReg(SparcOperand &Op) {
555 unsigned Reg = Op.getReg();
556 unsigned regIdx = 0;
557 switch (Op.Reg.Kind) {
558 default: llvm_unreachable("Unexpected register kind!");
559 case rk_FloatReg:
560 regIdx = Reg - Sparc::F0;
561 if (regIdx % 4 || regIdx > 31)
562 return false;
563 Reg = QuadFPRegs[regIdx / 4];
564 break;
565 case rk_DoubleReg:
566 regIdx = Reg - Sparc::D0;
567 if (regIdx % 2 || regIdx > 31)
568 return false;
569 Reg = QuadFPRegs[regIdx / 2];
570 break;
571 }
572 Op.Reg.RegNum = Reg;
573 Op.Reg.Kind = rk_QuadReg;
574 return true;
575 }
576
577 static bool MorphToCoprocPairReg(SparcOperand &Op) {
578 unsigned Reg = Op.getReg();
579 assert(Op.Reg.Kind == rk_CoprocReg);
580 unsigned regIdx = 32;
581 if (Reg >= Sparc::C0 && Reg <= Sparc::C31)
582 regIdx = Reg - Sparc::C0;
583 if (regIdx % 2 || regIdx > 31)
584 return false;
585 Op.Reg.RegNum = CoprocPairRegs[regIdx / 2];
586 Op.Reg.Kind = rk_CoprocPairReg;
587 return true;
588 }
589
590 static std::unique_ptr<SparcOperand>
591 MorphToMEMrr(unsigned Base, std::unique_ptr<SparcOperand> Op) {
592 unsigned offsetReg = Op->getReg();
593 Op->Kind = k_MemoryReg;
594 Op->Mem.Base = Base;
595 Op->Mem.OffsetReg = offsetReg;
596 Op->Mem.Off = nullptr;
597 return Op;
598 }
599
600 static std::unique_ptr<SparcOperand>
601 CreateMEMr(unsigned Base, SMLoc S, SMLoc E) {
602 auto Op = std::make_unique<SparcOperand>(k_MemoryReg);
603 Op->Mem.Base = Base;
604 Op->Mem.OffsetReg = Sparc::G0; // always 0
605 Op->Mem.Off = nullptr;
606 Op->StartLoc = S;
607 Op->EndLoc = E;
608 return Op;
609 }
610
611 static std::unique_ptr<SparcOperand>
612 MorphToMEMri(unsigned Base, std::unique_ptr<SparcOperand> Op) {
613 const MCExpr *Imm = Op->getImm();
614 Op->Kind = k_MemoryImm;
615 Op->Mem.Base = Base;
616 Op->Mem.OffsetReg = 0;
617 Op->Mem.Off = Imm;
618 return Op;
619 }
620};
621
622} // end anonymous namespace
623
624#define GET_MATCHER_IMPLEMENTATION
625#define GET_REGISTER_MATCHER
626#define GET_MNEMONIC_SPELL_CHECKER
627#include "SparcGenAsmMatcher.inc"
628
629// Use a custom function instead of the one from SparcGenAsmMatcher
630// so we can differentiate between unavailable and unknown instructions.
631SparcAsmParser::MatchResultTy
632SparcAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {
633 // Process all MnemonicAliases to remap the mnemonic.
634 applyMnemonicAliases(Mnemonic, getAvailableFeatures(), VariantID);
635
636 // Find the appropriate table for this asm variant.
637 const MatchEntry *Start, *End;
638 switch (VariantID) {
639 default:
640 llvm_unreachable("invalid variant!");
641 case 0:
642 Start = std::begin(MatchTable0);
643 End = std::end(MatchTable0);
644 break;
645 }
646
647 // Search the table.
648 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
649
650 if (MnemonicRange.first == MnemonicRange.second)
651 return Match_MnemonicFail;
652
653 for (const MatchEntry *it = MnemonicRange.first, *ie = MnemonicRange.second;
654 it != ie; ++it) {
655 const FeatureBitset &RequiredFeatures =
656 FeatureBitsets[it->RequiredFeaturesIdx];
657 if ((getAvailableFeatures() & RequiredFeatures) == RequiredFeatures)
658 return Match_Success;
659 }
660 return Match_MissingFeature;
661}
662
663bool SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
664 SmallVectorImpl<MCInst> &Instructions) {
665 MCOperand MCRegOp = Inst.getOperand(0);
666 MCOperand MCValOp = Inst.getOperand(1);
667 assert(MCRegOp.isReg());
668 assert(MCValOp.isImm() || MCValOp.isExpr());
669
670 // the imm operand can be either an expression or an immediate.
671 bool IsImm = Inst.getOperand(1).isImm();
672 int64_t RawImmValue = IsImm ? MCValOp.getImm() : 0;
673
674 // Allow either a signed or unsigned 32-bit immediate.
675 if (RawImmValue < -2147483648LL || RawImmValue > 4294967295LL) {
676 return Error(IDLoc,
677 "set: argument must be between -2147483648 and 4294967295");
678 }
679
680 // If the value was expressed as a large unsigned number, that's ok.
681 // We want to see if it "looks like" a small signed number.
682 int32_t ImmValue = RawImmValue;
683 // For 'set' you can't use 'or' with a negative operand on V9 because
684 // that would splat the sign bit across the upper half of the destination
685 // register, whereas 'set' is defined to zero the high 32 bits.
686 bool IsEffectivelyImm13 =
687 IsImm && ((is64Bit() ? 0 : -4096) <= ImmValue && ImmValue < 4096);
688 const MCExpr *ValExpr;
689 if (IsImm)
690 ValExpr = MCConstantExpr::create(ImmValue, getContext());
691 else
692 ValExpr = MCValOp.getExpr();
693
694 MCOperand PrevReg = MCOperand::createReg(Sparc::G0);
695
696 // If not just a signed imm13 value, then either we use a 'sethi' with a
697 // following 'or', or a 'sethi' by itself if there are no more 1 bits.
698 // In either case, start with the 'sethi'.
699 if (!IsEffectivelyImm13) {
700 MCInst TmpInst;
701 const MCExpr *Expr = adjustPICRelocation(SparcMCExpr::VK_Sparc_HI, ValExpr);
702 TmpInst.setLoc(IDLoc);
703 TmpInst.setOpcode(SP::SETHIi);
704 TmpInst.addOperand(MCRegOp);
705 TmpInst.addOperand(MCOperand::createExpr(Expr));
706 Instructions.push_back(TmpInst);
707 PrevReg = MCRegOp;
708 }
709
710 // The low bits require touching in 3 cases:
711 // * A non-immediate value will always require both instructions.
712 // * An effectively imm13 value needs only an 'or' instruction.
713 // * Otherwise, an immediate that is not effectively imm13 requires the
714 // 'or' only if bits remain after clearing the 22 bits that 'sethi' set.
715 // If the low bits are known zeros, there's nothing to do.
716 // In the second case, and only in that case, must we NOT clear
717 // bits of the immediate value via the %lo() assembler function.
718 // Note also, the 'or' instruction doesn't mind a large value in the case
719 // where the operand to 'set' was 0xFFFFFzzz - it does exactly what you mean.
720 if (!IsImm || IsEffectivelyImm13 || (ImmValue & 0x3ff)) {
721 MCInst TmpInst;
722 const MCExpr *Expr;
723 if (IsEffectivelyImm13)
724 Expr = ValExpr;
725 else
726 Expr = adjustPICRelocation(SparcMCExpr::VK_Sparc_LO, ValExpr);
727 TmpInst.setLoc(IDLoc);
728 TmpInst.setOpcode(SP::ORri);
729 TmpInst.addOperand(MCRegOp);
730 TmpInst.addOperand(PrevReg);
731 TmpInst.addOperand(MCOperand::createExpr(Expr));
732 Instructions.push_back(TmpInst);
733 }
734 return false;
735}
736
737bool SparcAsmParser::expandSETX(MCInst &Inst, SMLoc IDLoc,
738 SmallVectorImpl<MCInst> &Instructions) {
739 MCOperand MCRegOp = Inst.getOperand(0);
740 MCOperand MCValOp = Inst.getOperand(1);
741 MCOperand MCTmpOp = Inst.getOperand(2);
742 assert(MCRegOp.isReg() && MCTmpOp.isReg());
743 assert(MCValOp.isImm() || MCValOp.isExpr());
744
745 // the imm operand can be either an expression or an immediate.
746 bool IsImm = MCValOp.isImm();
747 int64_t ImmValue = IsImm ? MCValOp.getImm() : 0;
748
749 const MCExpr *ValExpr = IsImm ? MCConstantExpr::create(ImmValue, getContext())
750 : MCValOp.getExpr();
751
752 // Very small immediates can be expressed directly as a single `or`.
753 if (IsImm && isInt<13>(ImmValue)) {
754 // or rd, val, rd
755 Instructions.push_back(MCInstBuilder(SP::ORri)
756 .addReg(MCRegOp.getReg())
757 .addReg(Sparc::G0)
758 .addExpr(ValExpr));
759 return false;
760 }
761
762 // Otherwise, first we set the lower half of the register.
763
764 // sethi %hi(val), rd
765 Instructions.push_back(
766 MCInstBuilder(SP::SETHIi)
767 .addReg(MCRegOp.getReg())
768 .addExpr(adjustPICRelocation(SparcMCExpr::VK_Sparc_HI, ValExpr)));
769 // or rd, %lo(val), rd
770 Instructions.push_back(
771 MCInstBuilder(SP::ORri)
772 .addReg(MCRegOp.getReg())
773 .addReg(MCRegOp.getReg())
774 .addExpr(adjustPICRelocation(SparcMCExpr::VK_Sparc_LO, ValExpr)));
775
776 // Small positive immediates can be expressed as a single `sethi`+`or`
777 // combination, so we can just return here.
778 if (IsImm && isUInt<32>(ImmValue))
779 return false;
780
781 // For bigger immediates, we need to generate the upper half, then shift and
782 // merge it with the lower half that has just been generated above.
783
784 // sethi %hh(val), tmp
785 Instructions.push_back(
786 MCInstBuilder(SP::SETHIi)
787 .addReg(MCTmpOp.getReg())
788 .addExpr(adjustPICRelocation(SparcMCExpr::VK_Sparc_HH, ValExpr)));
789 // or tmp, %hm(val), tmp
790 Instructions.push_back(
791 MCInstBuilder(SP::ORri)
792 .addReg(MCTmpOp.getReg())
793 .addReg(MCTmpOp.getReg())
794 .addExpr(adjustPICRelocation(SparcMCExpr::VK_Sparc_HM, ValExpr)));
795 // sllx tmp, 32, tmp
796 Instructions.push_back(MCInstBuilder(SP::SLLXri)
797 .addReg(MCTmpOp.getReg())
798 .addReg(MCTmpOp.getReg())
799 .addImm(32));
800 // or tmp, rd, rd
801 Instructions.push_back(MCInstBuilder(SP::ORrr)
802 .addReg(MCRegOp.getReg())
803 .addReg(MCTmpOp.getReg())
804 .addReg(MCRegOp.getReg()));
805
806 return false;
807}
808
809bool SparcAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
811 MCStreamer &Out,
813 bool MatchingInlineAsm) {
814 MCInst Inst;
816 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
817 MatchingInlineAsm);
818 switch (MatchResult) {
819 case Match_Success: {
820 switch (Inst.getOpcode()) {
821 default:
822 Inst.setLoc(IDLoc);
823 Instructions.push_back(Inst);
824 break;
825 case SP::SET:
826 if (expandSET(Inst, IDLoc, Instructions))
827 return true;
828 break;
829 case SP::SETX:
830 if (expandSETX(Inst, IDLoc, Instructions))
831 return true;
832 break;
833 }
834
835 for (const MCInst &I : Instructions) {
836 Out.emitInstruction(I, getSTI());
837 }
838 return false;
839 }
840
841 case Match_MissingFeature:
842 return Error(IDLoc,
843 "instruction requires a CPU feature not currently enabled");
844
845 case Match_InvalidOperand: {
846 SMLoc ErrorLoc = IDLoc;
847 if (ErrorInfo != ~0ULL) {
848 if (ErrorInfo >= Operands.size())
849 return Error(IDLoc, "too few operands for instruction");
850
851 ErrorLoc = ((SparcOperand &)*Operands[ErrorInfo]).getStartLoc();
852 if (ErrorLoc == SMLoc())
853 ErrorLoc = IDLoc;
854 }
855
856 return Error(ErrorLoc, "invalid operand for instruction");
857 }
858 case Match_MnemonicFail:
859 return Error(IDLoc, "invalid instruction mnemonic");
860 }
861 llvm_unreachable("Implement any new match types added!");
862}
863
864bool SparcAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
865 SMLoc &EndLoc) {
866 if (!tryParseRegister(Reg, StartLoc, EndLoc).isSuccess())
867 return Error(StartLoc, "invalid register name");
868 return false;
869}
870
871ParseStatus SparcAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
872 SMLoc &EndLoc) {
873 const AsmToken &Tok = Parser.getTok();
874 StartLoc = Tok.getLoc();
875 EndLoc = Tok.getEndLoc();
876 Reg = Sparc::NoRegister;
877 if (getLexer().getKind() != AsmToken::Percent)
879 Parser.Lex();
880 unsigned RegKind = SparcOperand::rk_None;
881 Reg = matchRegisterName(Tok, RegKind);
882 if (Reg) {
883 Parser.Lex();
885 }
886
887 getLexer().UnLex(Tok);
889}
890
891bool SparcAsmParser::parseInstruction(ParseInstructionInfo &Info,
892 StringRef Name, SMLoc NameLoc,
894 // Validate and reject unavailable mnemonics early before
895 // running any operand parsing.
896 // This is needed because some operands (mainly memory ones)
897 // differ between V8 and V9 ISA and so any operand parsing errors
898 // will cause IAS to bail out before it reaches matchAndEmitInstruction
899 // (where the instruction as a whole, including the mnemonic, is validated
900 // once again just before emission).
901 // As a nice side effect this also allows us to reject unknown
902 // instructions and suggest replacements.
903 MatchResultTy MS = mnemonicIsValid(Name, 0);
904 switch (MS) {
905 case Match_Success:
906 break;
907 case Match_MissingFeature:
908 return Error(NameLoc,
909 "instruction requires a CPU feature not currently enabled");
910 case Match_MnemonicFail:
911 return Error(NameLoc,
912 "invalid instruction mnemonic" +
913 SparcMnemonicSpellCheck(Name, getAvailableFeatures(), 0));
914 default:
915 llvm_unreachable("invalid return status!");
916 }
917
918 // First operand in MCInst is instruction mnemonic.
919 Operands.push_back(SparcOperand::CreateToken(Name, NameLoc));
920
921 // apply mnemonic aliases, if any, so that we can parse operands correctly.
922 applyMnemonicAliases(Name, getAvailableFeatures(), 0);
923
924 if (getLexer().isNot(AsmToken::EndOfStatement)) {
925 // Read the first operand.
926 if (getLexer().is(AsmToken::Comma)) {
927 if (!parseBranchModifiers(Operands).isSuccess()) {
928 SMLoc Loc = getLexer().getLoc();
929 return Error(Loc, "unexpected token");
930 }
931 }
932 if (!parseOperand(Operands, Name).isSuccess()) {
933 SMLoc Loc = getLexer().getLoc();
934 return Error(Loc, "unexpected token");
935 }
936
937 while (getLexer().is(AsmToken::Comma) || getLexer().is(AsmToken::Plus)) {
938 if (getLexer().is(AsmToken::Plus)) {
939 // Plus tokens are significant in software_traps (p83, sparcv8.pdf). We must capture them.
940 Operands.push_back(SparcOperand::CreateToken("+", Parser.getTok().getLoc()));
941 }
942 Parser.Lex(); // Eat the comma or plus.
943 // Parse and remember the operand.
944 if (!parseOperand(Operands, Name).isSuccess()) {
945 SMLoc Loc = getLexer().getLoc();
946 return Error(Loc, "unexpected token");
947 }
948 }
949 }
950 if (getLexer().isNot(AsmToken::EndOfStatement)) {
951 SMLoc Loc = getLexer().getLoc();
952 return Error(Loc, "unexpected token");
953 }
954 Parser.Lex(); // Consume the EndOfStatement.
955 return false;
956}
957
958ParseStatus SparcAsmParser::parseDirective(AsmToken DirectiveID) {
959 StringRef IDVal = DirectiveID.getString();
960
961 if (IDVal == ".register") {
962 // For now, ignore .register directive.
963 Parser.eatToEndOfStatement();
965 }
966 if (IDVal == ".proc") {
967 // For compatibility, ignore this directive.
968 // (It's supposed to be an "optimization" in the Sun assembler)
969 Parser.eatToEndOfStatement();
971 }
972
973 // Let the MC layer to handle other directives.
975}
976
977ParseStatus SparcAsmParser::parseMEMOperand(OperandVector &Operands) {
978 SMLoc S, E;
979
980 std::unique_ptr<SparcOperand> LHS;
981 if (!parseSparcAsmOperand(LHS).isSuccess())
983
984 // Single immediate operand
985 if (LHS->isImm()) {
986 Operands.push_back(SparcOperand::MorphToMEMri(Sparc::G0, std::move(LHS)));
988 }
989
990 if (!LHS->isIntReg())
991 return Error(LHS->getStartLoc(), "invalid register kind for this operand");
992
993 AsmToken Tok = getLexer().getTok();
994 // The plus token may be followed by a register or an immediate value, the
995 // minus one is always interpreted as sign for the immediate value
996 if (Tok.is(AsmToken::Plus) || Tok.is(AsmToken::Minus)) {
998
999 std::unique_ptr<SparcOperand> RHS;
1000 if (!parseSparcAsmOperand(RHS).isSuccess())
1001 return ParseStatus::NoMatch;
1002
1003 if (RHS->isReg() && !RHS->isIntReg())
1004 return Error(RHS->getStartLoc(),
1005 "invalid register kind for this operand");
1006
1007 Operands.push_back(
1008 RHS->isImm()
1009 ? SparcOperand::MorphToMEMri(LHS->getReg(), std::move(RHS))
1010 : SparcOperand::MorphToMEMrr(LHS->getReg(), std::move(RHS)));
1011
1012 return ParseStatus::Success;
1013 }
1014
1015 Operands.push_back(SparcOperand::CreateMEMr(LHS->getReg(), S, E));
1016 return ParseStatus::Success;
1017}
1018
1019template <unsigned N>
1020ParseStatus SparcAsmParser::parseShiftAmtImm(OperandVector &Operands) {
1021 SMLoc S = Parser.getTok().getLoc();
1023
1024 // This is a register, not an immediate
1025 if (getLexer().getKind() == AsmToken::Percent)
1026 return ParseStatus::NoMatch;
1027
1028 const MCExpr *Expr;
1029 if (getParser().parseExpression(Expr))
1030 return ParseStatus::Failure;
1031
1032 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
1033 if (!CE)
1034 return Error(S, "constant expression expected");
1035
1036 if (!isUInt<N>(CE->getValue()))
1037 return Error(S, "immediate shift value out of range");
1038
1039 Operands.push_back(SparcOperand::CreateImm(Expr, S, E));
1040 return ParseStatus::Success;
1041}
1042
1043template <SparcAsmParser::TailRelocKind Kind>
1044ParseStatus SparcAsmParser::parseTailRelocSym(OperandVector &Operands) {
1045 SMLoc S = getLoc();
1047
1048 auto MatchesKind = [](SparcMCExpr::VariantKind VK) -> bool {
1049 switch (Kind) {
1050 case TailRelocKind::Load_GOT:
1051 // Non-TLS relocations on ld (or ldx).
1052 // ld [%rr + %rr], %rr, %rel(sym)
1054 case TailRelocKind::Add_TLS:
1055 // TLS relocations on add.
1056 // add %rr, %rr, %rr, %rel(sym)
1057 switch (VK) {
1062 return true;
1063 default:
1064 return false;
1065 }
1066 case TailRelocKind::Load_TLS:
1067 // TLS relocations on ld (or ldx).
1068 // ld[x] %addr, %rr, %rel(sym)
1069 switch (VK) {
1072 return true;
1073 default:
1074 return false;
1075 }
1076 case TailRelocKind::Call_TLS:
1077 // TLS relocations on call.
1078 // call sym, %rel(sym)
1079 switch (VK) {
1082 return true;
1083 default:
1084 return false;
1085 }
1086 }
1087 llvm_unreachable("Unhandled SparcAsmParser::TailRelocKind enum");
1088 };
1089
1090 if (getLexer().getKind() != AsmToken::Percent)
1091 return ParseStatus::NoMatch;
1092
1093 const AsmToken Tok = Parser.getTok();
1094 getParser().Lex(); // Eat '%'
1095
1096 if (getLexer().getKind() != AsmToken::Identifier)
1097 return Error(getLoc(), "expected valid identifier for operand modifier");
1098
1099 StringRef Name = getParser().getTok().getIdentifier();
1102 return Error(getLoc(), "invalid operand modifier");
1103
1104 if (!MatchesKind(VK)) {
1105 // Did not match the specified set of relocation types, put '%' back.
1106 getLexer().UnLex(Tok);
1107 return ParseStatus::NoMatch;
1108 }
1109
1110 Parser.Lex(); // Eat the identifier.
1111 if (getLexer().getKind() != AsmToken::LParen)
1112 return Error(getLoc(), "expected '('");
1113
1114 getParser().Lex(); // Eat '('
1115 const MCExpr *SubExpr;
1116 if (getParser().parseParenExpression(SubExpr, E))
1117 return ParseStatus::Failure;
1118
1119 const MCExpr *Val = adjustPICRelocation(VK, SubExpr);
1120 Operands.push_back(SparcOperand::CreateTailRelocSym(Val, S, E));
1121 return ParseStatus::Success;
1122}
1123
1124ParseStatus SparcAsmParser::parseMembarTag(OperandVector &Operands) {
1125 SMLoc S = Parser.getTok().getLoc();
1126 const MCExpr *EVal;
1127 int64_t ImmVal = 0;
1128
1129 std::unique_ptr<SparcOperand> Mask;
1130 if (parseSparcAsmOperand(Mask).isSuccess()) {
1131 if (!Mask->isImm() || !Mask->getImm()->evaluateAsAbsolute(ImmVal) ||
1132 ImmVal < 0 || ImmVal > 127)
1133 return Error(S, "invalid membar mask number");
1134 }
1135
1136 while (getLexer().getKind() == AsmToken::Hash) {
1137 SMLoc TagStart = getLexer().getLoc();
1138 Parser.Lex(); // Eat the '#'.
1139 unsigned MaskVal = StringSwitch<unsigned>(Parser.getTok().getString())
1140 .Case("LoadLoad", 0x1)
1141 .Case("StoreLoad", 0x2)
1142 .Case("LoadStore", 0x4)
1143 .Case("StoreStore", 0x8)
1144 .Case("Lookaside", 0x10)
1145 .Case("MemIssue", 0x20)
1146 .Case("Sync", 0x40)
1147 .Default(0);
1148
1149 Parser.Lex(); // Eat the identifier token.
1150
1151 if (!MaskVal)
1152 return Error(TagStart, "unknown membar tag");
1153
1154 ImmVal |= MaskVal;
1155
1156 if (getLexer().getKind() == AsmToken::Pipe)
1157 Parser.Lex(); // Eat the '|'.
1158 }
1159
1160 EVal = MCConstantExpr::create(ImmVal, getContext());
1161 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1162 Operands.push_back(SparcOperand::CreateImm(EVal, S, E));
1163 return ParseStatus::Success;
1164}
1165
1166ParseStatus SparcAsmParser::parseASITag(OperandVector &Operands) {
1167 SMLoc S = Parser.getTok().getLoc();
1168 SMLoc E = Parser.getTok().getEndLoc();
1169 int64_t ASIVal = 0;
1170
1171 if (getLexer().getKind() != AsmToken::Hash) {
1172 // If the ASI tag provided is not a named tag, then it
1173 // must be a constant expression.
1174 ParseStatus ParseExprStatus = parseExpression(ASIVal);
1175 if (!ParseExprStatus.isSuccess())
1176 return ParseExprStatus;
1177
1178 if (!isUInt<8>(ASIVal))
1179 return Error(S, "invalid ASI number, must be between 0 and 255");
1180
1181 Operands.push_back(SparcOperand::CreateASITag(ASIVal, S, E));
1182 return ParseStatus::Success;
1183 }
1184
1185 // For now we only support named tags for 64-bit/V9 systems.
1186 // TODO: add support for 32-bit/V8 systems.
1187 SMLoc TagStart = getLexer().peekTok(false).getLoc();
1188 Parser.Lex(); // Eat the '#'.
1189 const StringRef ASIName = Parser.getTok().getString();
1190 const SparcASITag::ASITag *ASITag = SparcASITag::lookupASITagByName(ASIName);
1191 if (!ASITag)
1192 ASITag = SparcASITag::lookupASITagByAltName(ASIName);
1193 Parser.Lex(); // Eat the identifier token.
1194
1195 if (!ASITag)
1196 return Error(TagStart, "unknown ASI tag");
1197
1198 ASIVal = ASITag->Encoding;
1199
1200 Operands.push_back(SparcOperand::CreateASITag(ASIVal, S, E));
1201 return ParseStatus::Success;
1202}
1203
1204ParseStatus SparcAsmParser::parsePrefetchTag(OperandVector &Operands) {
1205 SMLoc S = Parser.getTok().getLoc();
1206 SMLoc E = Parser.getTok().getEndLoc();
1207 int64_t PrefetchVal = 0;
1208
1209 if (getLexer().getKind() != AsmToken::Hash) {
1210 // If the prefetch tag provided is not a named tag, then it
1211 // must be a constant expression.
1212 ParseStatus ParseExprStatus = parseExpression(PrefetchVal);
1213 if (!ParseExprStatus.isSuccess())
1214 return ParseExprStatus;
1215
1216 if (!isUInt<8>(PrefetchVal))
1217 return Error(S, "invalid prefetch number, must be between 0 and 31");
1218
1219 Operands.push_back(SparcOperand::CreatePrefetchTag(PrefetchVal, S, E));
1220 return ParseStatus::Success;
1221 }
1222
1223 SMLoc TagStart = getLexer().peekTok(false).getLoc();
1224 Parser.Lex(); // Eat the '#'.
1225 const StringRef PrefetchName = Parser.getTok().getString();
1226 const SparcPrefetchTag::PrefetchTag *PrefetchTag =
1227 SparcPrefetchTag::lookupPrefetchTagByName(PrefetchName);
1228 Parser.Lex(); // Eat the identifier token.
1229
1230 if (!PrefetchTag)
1231 return Error(TagStart, "unknown prefetch tag");
1232
1233 PrefetchVal = PrefetchTag->Encoding;
1234
1235 Operands.push_back(SparcOperand::CreatePrefetchTag(PrefetchVal, S, E));
1236 return ParseStatus::Success;
1237}
1238
1239ParseStatus SparcAsmParser::parseCallTarget(OperandVector &Operands) {
1240 SMLoc S = Parser.getTok().getLoc();
1242
1243 switch (getLexer().getKind()) {
1244 default:
1245 return ParseStatus::NoMatch;
1246 case AsmToken::LParen:
1247 case AsmToken::Integer:
1249 case AsmToken::Dot:
1250 break;
1251 }
1252
1253 const MCExpr *DestValue;
1254 if (getParser().parseExpression(DestValue))
1255 return ParseStatus::NoMatch;
1256
1257 bool IsPic = getContext().getObjectFileInfo()->isPositionIndependent();
1260
1261 const MCExpr *DestExpr = SparcMCExpr::create(Kind, DestValue, getContext());
1262 Operands.push_back(SparcOperand::CreateImm(DestExpr, S, E));
1263 return ParseStatus::Success;
1264}
1265
1266ParseStatus SparcAsmParser::parseOperand(OperandVector &Operands,
1267 StringRef Mnemonic) {
1268
1269 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic);
1270
1271 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1272 // there was a match, but an error occurred, in which case, just return that
1273 // the operand parsing failed.
1274 if (Res.isSuccess() || Res.isFailure())
1275 return Res;
1276
1277 if (getLexer().is(AsmToken::LBrac)) {
1278 // Memory operand
1279 Operands.push_back(SparcOperand::CreateToken("[",
1280 Parser.getTok().getLoc()));
1281 Parser.Lex(); // Eat the [
1282
1283 if (Mnemonic == "cas" || Mnemonic == "casl" || Mnemonic == "casa" ||
1284 Mnemonic == "casx" || Mnemonic == "casxl" || Mnemonic == "casxa") {
1285 SMLoc S = Parser.getTok().getLoc();
1286 if (getLexer().getKind() != AsmToken::Percent)
1287 return ParseStatus::NoMatch;
1288 Parser.Lex(); // eat %
1289
1290 unsigned RegKind;
1291 MCRegister Reg = matchRegisterName(Parser.getTok(), RegKind);
1292 if (!Reg)
1293 return ParseStatus::NoMatch;
1294
1295 Parser.Lex(); // Eat the identifier token.
1297 Operands.push_back(SparcOperand::CreateReg(Reg, RegKind, S, E));
1299 } else {
1300 Res = parseMEMOperand(Operands);
1301 }
1302
1303 if (!Res.isSuccess())
1304 return Res;
1305
1306 if (!getLexer().is(AsmToken::RBrac))
1307 return ParseStatus::Failure;
1308
1309 Operands.push_back(SparcOperand::CreateToken("]",
1310 Parser.getTok().getLoc()));
1311 Parser.Lex(); // Eat the ]
1312
1313 // Parse an optional address-space identifier after the address.
1314 // This will be either an immediate constant expression, or, on 64-bit
1315 // processors, the %asi register.
1316 if (getLexer().is(AsmToken::Percent)) {
1317 SMLoc S = Parser.getTok().getLoc();
1318 if (!is64Bit())
1319 return Error(
1320 S, "malformed ASI tag, must be a constant integer expression");
1321
1322 Parser.Lex(); // Eat the %.
1323 const AsmToken Tok = Parser.getTok();
1324 if (Tok.is(AsmToken::Identifier) && Tok.getString() == "asi") {
1325 // Here we patch the MEM operand from [base + %g0] into [base + 0]
1326 // as memory operations with ASI tag stored in %asi register needs
1327 // to use immediate offset. We need to do this because Reg addressing
1328 // will be parsed as Reg+G0 initially.
1329 // This allows forms such as `ldxa [%o0] %asi, %o0` to parse correctly.
1330 SparcOperand &OldMemOp = (SparcOperand &)*Operands[Operands.size() - 2];
1331 if (OldMemOp.isMEMrr()) {
1332 if (OldMemOp.getMemOffsetReg() != Sparc::G0) {
1333 return Error(S, "invalid operand for instruction");
1334 }
1335 Operands[Operands.size() - 2] = SparcOperand::MorphToMEMri(
1336 OldMemOp.getMemBase(),
1337 SparcOperand::CreateImm(MCConstantExpr::create(0, getContext()),
1338 OldMemOp.getStartLoc(),
1339 OldMemOp.getEndLoc()));
1340 }
1341 Parser.Lex(); // Eat the identifier.
1342 // In this context, we convert the register operand into
1343 // a plain "%asi" token since the register access is already
1344 // implicit in the instruction definition and encoding.
1345 // See LoadASI/StoreASI in SparcInstrInfo.td.
1346 Operands.push_back(SparcOperand::CreateToken("%asi", S));
1347 return ParseStatus::Success;
1348 }
1349
1350 return Error(S, "malformed ASI tag, must be %asi, a constant integer "
1351 "expression, or a named tag");
1352 }
1353
1354 // If we're not at the end of statement and the next token is not a comma,
1355 // then it is an immediate ASI value.
1356 if (getLexer().isNot(AsmToken::EndOfStatement) &&
1357 getLexer().isNot(AsmToken::Comma))
1358 return parseASITag(Operands);
1359 return ParseStatus::Success;
1360 }
1361
1362 std::unique_ptr<SparcOperand> Op;
1363
1364 Res = parseSparcAsmOperand(Op, (Mnemonic == "call"));
1365 if (!Res.isSuccess() || !Op)
1366 return ParseStatus::Failure;
1367
1368 // Push the parsed operand into the list of operands
1369 Operands.push_back(std::move(Op));
1370
1371 return ParseStatus::Success;
1372}
1373
1375SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op,
1376 bool isCall) {
1377 SMLoc S = Parser.getTok().getLoc();
1378 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1379 const MCExpr *EVal;
1380
1381 Op = nullptr;
1382 switch (getLexer().getKind()) {
1383 default: break;
1384
1385 case AsmToken::Percent: {
1386 Parser.Lex(); // Eat the '%'.
1387 unsigned RegKind;
1388 if (MCRegister Reg = matchRegisterName(Parser.getTok(), RegKind)) {
1389 StringRef Name = Parser.getTok().getString();
1390 Parser.Lex(); // Eat the identifier token.
1391 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1392 if (Reg == Sparc::ICC && Name == "xcc")
1393 Op = SparcOperand::CreateToken("%xcc", S);
1394 else
1395 Op = SparcOperand::CreateReg(Reg, RegKind, S, E);
1396 break;
1397 }
1398 if (matchSparcAsmModifiers(EVal, E)) {
1399 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1400 Op = SparcOperand::CreateImm(EVal, S, E);
1401 }
1402 break;
1403 }
1404
1405 case AsmToken::Plus:
1406 case AsmToken::Minus:
1407 case AsmToken::Integer:
1408 case AsmToken::LParen:
1409 case AsmToken::Dot:
1411 if (getParser().parseExpression(EVal, E))
1412 break;
1413
1414 int64_t Res;
1415 if (!EVal->evaluateAsAbsolute(Res)) {
1417
1418 if (getContext().getObjectFileInfo()->isPositionIndependent()) {
1419 if (isCall)
1421 else
1423 }
1424 EVal = SparcMCExpr::create(Kind, EVal, getContext());
1425 }
1426 Op = SparcOperand::CreateImm(EVal, S, E);
1427 break;
1428 }
1430}
1431
1432ParseStatus SparcAsmParser::parseBranchModifiers(OperandVector &Operands) {
1433 // parse (,a|,pn|,pt)+
1434
1435 while (getLexer().is(AsmToken::Comma)) {
1436 Parser.Lex(); // Eat the comma
1437
1438 if (!getLexer().is(AsmToken::Identifier))
1439 return ParseStatus::Failure;
1440 StringRef modName = Parser.getTok().getString();
1441 if (modName == "a" || modName == "pn" || modName == "pt") {
1442 Operands.push_back(SparcOperand::CreateToken(modName,
1443 Parser.getTok().getLoc()));
1444 Parser.Lex(); // eat the identifier.
1445 }
1446 }
1447 return ParseStatus::Success;
1448}
1449
1450ParseStatus SparcAsmParser::parseExpression(int64_t &Val) {
1451 AsmToken Tok = getLexer().getTok();
1452
1453 if (!isPossibleExpression(Tok))
1454 return ParseStatus::NoMatch;
1455
1456 return getParser().parseAbsoluteExpression(Val);
1457}
1458
1459MCRegister SparcAsmParser::matchRegisterName(const AsmToken &Tok,
1460 unsigned &RegKind) {
1461 RegKind = SparcOperand::rk_None;
1462 if (!Tok.is(AsmToken::Identifier))
1463 return SP::NoRegister;
1464
1465 StringRef Name = Tok.getString();
1467 if (!Reg)
1468 Reg = MatchRegisterAltName(Name.lower());
1469
1470 if (Reg) {
1471 // Some registers have identical spellings. The generated matcher might
1472 // have chosen one or another spelling, e.g. "%fp" or "%i6" might have been
1473 // matched to either SP::I6 or SP::I6_I7. Other parts of SparcAsmParser
1474 // are not prepared for this, so we do some canonicalization.
1475
1476 // See the note in SparcRegisterInfo.td near ASRRegs register class.
1477 if (Reg == SP::ASR4 && Name == "tick") {
1478 RegKind = SparcOperand::rk_Special;
1479 return SP::TICK;
1480 }
1481
1482 if (MRI.getRegClass(SP::IntRegsRegClassID).contains(Reg)) {
1483 RegKind = SparcOperand::rk_IntReg;
1484 return Reg;
1485 }
1486 if (MRI.getRegClass(SP::FPRegsRegClassID).contains(Reg)) {
1487 RegKind = SparcOperand::rk_FloatReg;
1488 return Reg;
1489 }
1490 if (MRI.getRegClass(SP::CoprocRegsRegClassID).contains(Reg)) {
1491 RegKind = SparcOperand::rk_CoprocReg;
1492 return Reg;
1493 }
1494
1495 // Canonicalize G0_G1 ... G30_G31 etc. to G0 ... G30.
1496 if (MRI.getRegClass(SP::IntPairRegClassID).contains(Reg)) {
1497 RegKind = SparcOperand::rk_IntReg;
1498 return MRI.getSubReg(Reg, SP::sub_even);
1499 }
1500
1501 // Canonicalize D0 ... D15 to F0 ... F30.
1502 if (MRI.getRegClass(SP::DFPRegsRegClassID).contains(Reg)) {
1503 // D16 ... D31 do not have sub-registers.
1504 if (MCRegister SubReg = MRI.getSubReg(Reg, SP::sub_even)) {
1505 RegKind = SparcOperand::rk_FloatReg;
1506 return SubReg;
1507 }
1508 RegKind = SparcOperand::rk_DoubleReg;
1509 return Reg;
1510 }
1511
1512 // The generated matcher does not currently return QFP registers.
1513 // If it changes, we will need to handle them in a similar way.
1514 assert(!MRI.getRegClass(SP::QFPRegsRegClassID).contains(Reg));
1515
1516 // Canonicalize C0_C1 ... C30_C31 to C0 ... C30.
1517 if (MRI.getRegClass(SP::CoprocPairRegClassID).contains(Reg)) {
1518 RegKind = SparcOperand::rk_CoprocReg;
1519 return MRI.getSubReg(Reg, SP::sub_even);
1520 }
1521
1522 // Other registers do not need special handling.
1523 RegKind = SparcOperand::rk_Special;
1524 return Reg;
1525 }
1526
1527 // If we still have no match, try custom parsing.
1528 // Not all registers and their spellings are modeled in td files.
1529
1530 // %r0 - %r31
1531 int64_t RegNo = 0;
1532 if (Name.starts_with_insensitive("r") &&
1533 !Name.substr(1, 2).getAsInteger(10, RegNo) && RegNo < 31) {
1534 RegKind = SparcOperand::rk_IntReg;
1535 return IntRegs[RegNo];
1536 }
1537
1538 if (Name == "xcc") {
1539 // FIXME:: check 64bit.
1540 RegKind = SparcOperand::rk_Special;
1541 return SP::ICC;
1542 }
1543
1544 // JPS1 extension - aliases for ASRs
1545 // Section 5.2.11 - Ancillary State Registers (ASRs)
1546 if (Name == "pcr") {
1547 RegKind = SparcOperand::rk_Special;
1548 return SP::ASR16;
1549 }
1550 if (Name == "pic") {
1551 RegKind = SparcOperand::rk_Special;
1552 return SP::ASR17;
1553 }
1554 if (Name == "dcr") {
1555 RegKind = SparcOperand::rk_Special;
1556 return SP::ASR18;
1557 }
1558 if (Name == "gsr") {
1559 RegKind = SparcOperand::rk_Special;
1560 return SP::ASR19;
1561 }
1562 if (Name == "set_softint") {
1563 RegKind = SparcOperand::rk_Special;
1564 return SP::ASR20;
1565 }
1566 if (Name == "clear_softint") {
1567 RegKind = SparcOperand::rk_Special;
1568 return SP::ASR21;
1569 }
1570 if (Name == "softint") {
1571 RegKind = SparcOperand::rk_Special;
1572 return SP::ASR22;
1573 }
1574 if (Name == "tick_cmpr") {
1575 RegKind = SparcOperand::rk_Special;
1576 return SP::ASR23;
1577 }
1578 if (Name == "stick" || Name == "sys_tick") {
1579 RegKind = SparcOperand::rk_Special;
1580 return SP::ASR24;
1581 }
1582 if (Name == "stick_cmpr" || Name == "sys_tick_cmpr") {
1583 RegKind = SparcOperand::rk_Special;
1584 return SP::ASR25;
1585 }
1586
1587 return SP::NoRegister;
1588}
1589
1590// Determine if an expression contains a reference to the symbol
1591// "_GLOBAL_OFFSET_TABLE_".
1592static bool hasGOTReference(const MCExpr *Expr) {
1593 switch (Expr->getKind()) {
1594 case MCExpr::Target:
1595 if (const SparcMCExpr *SE = dyn_cast<SparcMCExpr>(Expr))
1596 return hasGOTReference(SE->getSubExpr());
1597 break;
1598
1599 case MCExpr::Constant:
1600 break;
1601
1602 case MCExpr::Binary: {
1603 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
1604 return hasGOTReference(BE->getLHS()) || hasGOTReference(BE->getRHS());
1605 }
1606
1607 case MCExpr::SymbolRef: {
1608 const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
1609 return (SymRef.getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_");
1610 }
1611
1612 case MCExpr::Unary:
1613 return hasGOTReference(cast<MCUnaryExpr>(Expr)->getSubExpr());
1614 }
1615 return false;
1616}
1617
1618const SparcMCExpr *
1619SparcAsmParser::adjustPICRelocation(SparcMCExpr::VariantKind VK,
1620 const MCExpr *subExpr) {
1621 // When in PIC mode, "%lo(...)" and "%hi(...)" behave differently.
1622 // If the expression refers contains _GLOBAL_OFFSET_TABLE, it is
1623 // actually a %pc10 or %pc22 relocation. Otherwise, they are interpreted
1624 // as %got10 or %got22 relocation.
1625
1626 if (getContext().getObjectFileInfo()->isPositionIndependent()) {
1627 switch(VK) {
1628 default: break;
1632 break;
1636 break;
1637 }
1638 }
1639
1640 return SparcMCExpr::create(VK, subExpr, getContext());
1641}
1642
1643bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
1644 SMLoc &EndLoc) {
1645 AsmToken Tok = Parser.getTok();
1646 if (!Tok.is(AsmToken::Identifier))
1647 return false;
1648
1649 StringRef name = Tok.getString();
1650
1652 switch (VK) {
1654 Error(getLoc(), "invalid operand modifier");
1655 return false;
1656
1666 // These are special-cased at tablegen level.
1667 return false;
1668
1669 default:
1670 break;
1671 }
1672
1673 Parser.Lex(); // Eat the identifier.
1674 if (Parser.getTok().getKind() != AsmToken::LParen)
1675 return false;
1676
1677 Parser.Lex(); // Eat the LParen token.
1678 const MCExpr *subExpr;
1679 if (Parser.parseParenExpression(subExpr, EndLoc))
1680 return false;
1681
1682 EVal = adjustPICRelocation(VK, subExpr);
1683 return true;
1684}
1685
1686bool SparcAsmParser::isPossibleExpression(const AsmToken &Token) {
1687 switch (Token.getKind()) {
1688 case AsmToken::LParen:
1689 case AsmToken::Integer:
1691 case AsmToken::Plus:
1692 case AsmToken::Minus:
1693 case AsmToken::Tilde:
1694 return true;
1695 default:
1696 return false;
1697 }
1698}
1699
1704}
1705
1706unsigned SparcAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,
1707 unsigned Kind) {
1708 SparcOperand &Op = (SparcOperand &)GOp;
1709 if (Op.isFloatOrDoubleReg()) {
1710 switch (Kind) {
1711 default: break;
1712 case MCK_DFPRegs:
1713 if (!Op.isFloatReg() || SparcOperand::MorphToDoubleReg(Op))
1715 break;
1716 case MCK_QFPRegs:
1717 if (SparcOperand::MorphToQuadReg(Op))
1719 break;
1720 }
1721 }
1722 if (Op.isIntReg() && Kind == MCK_IntPair) {
1723 if (SparcOperand::MorphToIntPairReg(Op))
1725 }
1726 if (Op.isCoprocReg() && Kind == MCK_CoprocPair) {
1727 if (SparcOperand::MorphToCoprocPairReg(Op))
1729 }
1730 return Match_InvalidOperand;
1731}
unsigned SubReg
unsigned const MachineRegisterInfo * MRI
static MCRegister MatchRegisterName(StringRef Name)
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
static bool addCallTargetOperands(MachineInstrBuilder &CallInst, MachineIRBuilder &MIRBuilder, AMDGPUCallLowering::CallLoweringInfo &Info)
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
static MCRegister MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:128
std::string Name
bool End
Definition: ELF_riscv.cpp:480
static LVOptions Options
Definition: LVOptions.cpp:25
#define I(x, y, z)
Definition: MD5.cpp:58
mir Rename Register Operands
unsigned Reg
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static const char * name
Definition: SMEABIPass.cpp:46
raw_pwrite_stream & OS
This file defines the SmallVector class.
static const MCPhysReg DoubleRegs[32]
static bool hasGOTReference(const MCExpr *Expr)
static const MCPhysReg IntRegs[32]
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSparcAsmParser()
static const MCPhysReg IntPairRegs[]
static const MCPhysReg QuadFPRegs[32]
static const MCPhysReg CoprocPairRegs[]
static bool is64Bit(const char *name)
Value * RHS
Value * LHS
Target independent representation for an assembler token.
Definition: MCAsmMacro.h:21
SMLoc getLoc() const
Definition: MCAsmLexer.cpp:26
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
Definition: MCAsmMacro.h:110
bool is(TokenKind K) const
Definition: MCAsmMacro.h:82
TokenKind getKind() const
Definition: MCAsmMacro.h:81
SMLoc getEndLoc() const
Definition: MCAsmLexer.cpp:30
This class represents an Operation in the Expression.
Base class for user error types.
Definition: Error.h:355
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
Container class for subtarget features.
Generic assembler parser interface, for use by target specific assembly parsers.
Definition: MCAsmParser.h:123
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
Definition: MCAsmParser.cpp:40
virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression, assuming that an initial '(' has already been consumed.
bool parseOptionalToken(AsmToken::TokenKind T)
Attempt to parse and consume token, returning true on success.
Definition: MCAsmParser.cpp:80
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
Binary assembler expressions.
Definition: MCExpr.h:493
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
Definition: MCExpr.h:640
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
Definition: MCExpr.h:643
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:222
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:34
@ Unary
Unary expressions.
Definition: MCExpr.h:40
@ Constant
Constant expressions.
Definition: MCExpr.h:38
@ SymbolRef
References to labels and assigned expressions.
Definition: MCExpr.h:39
@ Target
Target specific expression.
Definition: MCExpr.h:41
@ Binary
Binary expressions.
Definition: MCExpr.h:37
ExprKind getKind() const
Definition: MCExpr.h:78
MCInstBuilder & addReg(MCRegister Reg)
Add a new register operand.
Definition: MCInstBuilder.h:37
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
Definition: MCInstBuilder.h:43
MCInstBuilder & addExpr(const MCExpr *Val)
Add a new MCExpr operand.
Definition: MCInstBuilder.h:61
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:185
void setLoc(SMLoc loc)
Definition: MCInst.h:204
unsigned getOpcode() const
Definition: MCInst.h:199
void addOperand(const MCOperand Op)
Definition: MCInst.h:211
void setOpcode(unsigned Op)
Definition: MCInst.h:198
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:207
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:26
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:37
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:163
int64_t getImm() const
Definition: MCInst.h:81
static MCOperand createReg(MCRegister Reg)
Definition: MCInst.h:135
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:142
bool isImm() const
Definition: MCInst.h:63
bool isReg() const
Definition: MCInst.h:62
MCRegister getReg() const
Returns the register number.
Definition: MCInst.h:70
const MCExpr * getExpr() const
Definition: MCInst.h:115
bool isExpr() const
Definition: MCInst.h:66
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual SMLoc getStartLoc() const =0
getStartLoc - Get the location of the first token of this operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual bool isMem() const =0
isMem - Is this a memory operand?
virtual MCRegister getReg() const =0
virtual void print(raw_ostream &OS) const =0
print - Print a debug representation of the operand to the given stream.
virtual bool isToken() const =0
isToken - Is this a token operand?
virtual bool isImm() const =0
isImm - Is this an immediate operand?
virtual SMLoc getEndLoc() const =0
getEndLoc - Get the location of the last token of this operand.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
Streaming machine code generation interface.
Definition: MCStreamer.h:213
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Generic base class for all target subtargets.
const Triple & getTargetTriple() const
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:192
const MCSymbol & getSymbol() const
Definition: MCExpr.h:411
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:205
MCTargetAsmParser - Generic interface to target specific assembly parsers.
virtual ParseStatus parseDirective(AsmToken DirectiveID)
Parses a target-specific assembler directive.
virtual bool parseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
Parse one assembly instruction.
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
virtual bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
Recognize a series of operands of a parsed instruction as an actual MCInst and emit it to the specifi...
void setAvailableFeatures(const FeatureBitset &Value)
const MCSubtargetInfo & getSTI() const
virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind)
Allow a target to add special case operand matching for things that tblgen doesn't/can't handle effec...
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
Represents a location in source code.
Definition: SMLoc.h:23
static SMLoc getFromPointer(const char *Ptr)
Definition: SMLoc.h:36
constexpr const char * getPointer() const
Definition: SMLoc.h:34
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
static const SparcMCExpr * create(VariantKind Kind, const MCExpr *Expr, MCContext &Ctx)
Definition: SparcMCExpr.cpp:27
static VariantKind parseVariantKind(StringRef name)
Definition: SparcMCExpr.cpp:93
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:69
R Default(T Value)
Definition: StringSwitch.h:182
ArchType getArch() const
Get the parsed architecture type of this triple.
Definition: Triple.h:383
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition: BitmaskEnum.h:125
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
bool isIntReg(MCRegister Reg)
MCExpr const & getExpr(MCExpr const &Expr)
@ CE
Windows NT (Windows on ARM)
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Length
Definition: DWP.cpp:480
Target & getTheSparcTarget()
Target & getTheSparcV9Target()
DWARFExpression::Operation Op
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1873
Target & getTheSparcelTarget()
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
#define N
A record for a potential prefetch made during the initial scan of the loop.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...