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