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