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
9#include "MCTargetDesc/SparcMCAsmInfo.h"
10#include "MCTargetDesc/SparcMCTargetDesc.h"
11#include "TargetInfo/SparcTargetInfo.h"
12#include "llvm/ADT/SmallVector.h"
13#include "llvm/ADT/StringRef.h"
14#include "llvm/BinaryFormat/ELF.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"
19#include "llvm/MC/MCInstBuilder.h"
20#include "llvm/MC/MCInstrInfo.h"
21#include "llvm/MC/MCObjectFileInfo.h"
22#include "llvm/MC/MCParser/AsmLexer.h"
23#include "llvm/MC/MCParser/MCAsmParser.h"
24#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
25#include "llvm/MC/MCParser/MCTargetAsmParser.h"
26#include "llvm/MC/MCRegisterInfo.h"
27#include "llvm/MC/MCStreamer.h"
28#include "llvm/MC/MCSubtargetInfo.h"
29#include "llvm/MC/MCSymbol.h"
30#include "llvm/MC/TargetRegistry.h"
31#include "llvm/Support/Casting.h"
32#include "llvm/Support/Compiler.h"
33#include "llvm/Support/ErrorHandling.h"
34#include "llvm/Support/MathExtras.h"
35#include "llvm/Support/SMLoc.h"
36#include "llvm/Support/raw_ostream.h"
37#include "llvm/TargetParser/Triple.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,
76 uint64_t &ErrorInfo,
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(Directive: ".half", Alias: ".2byte");
148 Parser.addAliasForDirective(Directive: ".uahalf", Alias: ".2byte");
149 Parser.addAliasForDirective(Directive: ".word", Alias: ".4byte");
150 Parser.addAliasForDirective(Directive: ".uaword", Alias: ".4byte");
151 Parser.addAliasForDirective(Directive: ".nword", Alias: is64Bit() ? ".8byte" : ".4byte");
152 if (is64Bit())
153 Parser.addAliasForDirective(Directive: ".xword", Alias: ".8byte");
154
155 // Initialize the set of available features.
156 setAvailableFeatures(ComputeAvailableFeatures(FB: 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 unsigned RegNum;
239 RegisterKind Kind;
240 };
241
242 struct ImmOp {
243 const MCExpr *Val;
244 };
245
246 struct MemOp {
247 unsigned Base;
248 unsigned 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>(Val: 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>(Val: Imm.Val))
290 return isUInt<5>(x: 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>(Val: Imm.Val))
300 return isUInt<6>(x: 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.RegNum;
330 }
331
332 const MCExpr *getImm() const {
333 assert((Kind == k_Immediate) && "Invalid access!");
334 return Imm.Val;
335 }
336
337 unsigned getMemBase() const {
338 assert((Kind == k_MemoryReg || Kind == k_MemoryImm) && "Invalid access!");
339 return Mem.Base;
340 }
341
342 unsigned 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: OS << "Reg: #" << getReg() << "\n"; break;
380 case k_Immediate: OS << "Imm: " << getImm() << "\n"; break;
381 case k_MemoryReg: OS << "Mem: " << getMemBase() << "+"
382 << getMemOffsetReg() << "\n"; break;
383 case k_MemoryImm: assert(getMemOff() != nullptr);
384 OS << "Mem: " << getMemBase() << "+";
385 MAI.printExpr(OS, *getMemOff());
386 OS << "\n";
387 break;
388 case k_ASITag:
389 OS << "ASI tag: " << getASITag() << "\n";
390 break;
391 case k_PrefetchTag:
392 OS << "Prefetch tag: " << getPrefetchTag() << "\n";
393 break;
394 case k_TailRelocSym:
395 OS << "TailReloc: " << getTailRelocSym() << "\n";
396 break;
397 }
398 }
399
400 void addRegOperands(MCInst &Inst, unsigned N) const {
401 assert(N == 1 && "Invalid number of operands!");
402 Inst.addOperand(Op: MCOperand::createReg(Reg: getReg()));
403 }
404
405 void addImmOperands(MCInst &Inst, unsigned N) const {
406 assert(N == 1 && "Invalid number of operands!");
407 const MCExpr *Expr = getImm();
408 addExpr(Inst, Expr);
409 }
410
411 void addShiftAmtImm5Operands(MCInst &Inst, unsigned N) const {
412 assert(N == 1 && "Invalid number of operands!");
413 addExpr(Inst, Expr: getImm());
414 }
415 void addShiftAmtImm6Operands(MCInst &Inst, unsigned N) const {
416 assert(N == 1 && "Invalid number of operands!");
417 addExpr(Inst, Expr: getImm());
418 }
419
420 void addExpr(MCInst &Inst, const MCExpr *Expr) const{
421 // Add as immediate when possible. Null MCExpr = 0.
422 if (!Expr)
423 Inst.addOperand(Op: MCOperand::createImm(Val: 0));
424 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Val: Expr))
425 Inst.addOperand(Op: MCOperand::createImm(Val: CE->getValue()));
426 else
427 Inst.addOperand(Op: MCOperand::createExpr(Val: Expr));
428 }
429
430 void addMEMrrOperands(MCInst &Inst, unsigned N) const {
431 assert(N == 2 && "Invalid number of operands!");
432
433 Inst.addOperand(Op: MCOperand::createReg(Reg: getMemBase()));
434
435 assert(getMemOffsetReg() != 0 && "Invalid offset");
436 Inst.addOperand(Op: MCOperand::createReg(Reg: getMemOffsetReg()));
437 }
438
439 void addMEMriOperands(MCInst &Inst, unsigned N) const {
440 assert(N == 2 && "Invalid number of operands!");
441
442 Inst.addOperand(Op: MCOperand::createReg(Reg: getMemBase()));
443
444 const MCExpr *Expr = getMemOff();
445 addExpr(Inst, Expr);
446 }
447
448 void addASITagOperands(MCInst &Inst, unsigned N) const {
449 assert(N == 1 && "Invalid number of operands!");
450 Inst.addOperand(Op: MCOperand::createImm(Val: getASITag()));
451 }
452
453 void addPrefetchTagOperands(MCInst &Inst, unsigned N) const {
454 assert(N == 1 && "Invalid number of operands!");
455 Inst.addOperand(Op: MCOperand::createImm(Val: getPrefetchTag()));
456 }
457
458 void addMembarTagOperands(MCInst &Inst, unsigned N) const {
459 assert(N == 1 && "Invalid number of operands!");
460 const MCExpr *Expr = getImm();
461 addExpr(Inst, Expr);
462 }
463
464 void addCallTargetOperands(MCInst &Inst, unsigned N) const {
465 assert(N == 1 && "Invalid number of operands!");
466 addExpr(Inst, Expr: getImm());
467 }
468
469 void addTailRelocSymOperands(MCInst &Inst, unsigned N) const {
470 assert(N == 1 && "Invalid number of operands!");
471 addExpr(Inst, Expr: getTailRelocSym());
472 }
473
474 static std::unique_ptr<SparcOperand> CreateToken(StringRef Str, SMLoc S) {
475 auto Op = std::make_unique<SparcOperand>(args: k_Token);
476 Op->Tok.Data = Str.data();
477 Op->Tok.Length = Str.size();
478 Op->StartLoc = S;
479 Op->EndLoc = S;
480 return Op;
481 }
482
483 static std::unique_ptr<SparcOperand> CreateReg(unsigned RegNum, unsigned Kind,
484 SMLoc S, SMLoc E) {
485 auto Op = std::make_unique<SparcOperand>(args: k_Register);
486 Op->Reg.RegNum = RegNum;
487 Op->Reg.Kind = (SparcOperand::RegisterKind)Kind;
488 Op->StartLoc = S;
489 Op->EndLoc = E;
490 return Op;
491 }
492
493 static std::unique_ptr<SparcOperand> CreateImm(const MCExpr *Val, SMLoc S,
494 SMLoc E) {
495 auto Op = std::make_unique<SparcOperand>(args: k_Immediate);
496 Op->Imm.Val = Val;
497 Op->StartLoc = S;
498 Op->EndLoc = E;
499 return Op;
500 }
501
502 static std::unique_ptr<SparcOperand> CreateASITag(unsigned Val, SMLoc S,
503 SMLoc E) {
504 auto Op = std::make_unique<SparcOperand>(args: k_ASITag);
505 Op->ASI = Val;
506 Op->StartLoc = S;
507 Op->EndLoc = E;
508 return Op;
509 }
510
511 static std::unique_ptr<SparcOperand> CreatePrefetchTag(unsigned Val, SMLoc S,
512 SMLoc E) {
513 auto Op = std::make_unique<SparcOperand>(args: k_PrefetchTag);
514 Op->Prefetch = Val;
515 Op->StartLoc = S;
516 Op->EndLoc = E;
517 return Op;
518 }
519
520 static std::unique_ptr<SparcOperand> CreateTailRelocSym(const MCExpr *Val,
521 SMLoc S, SMLoc E) {
522 auto Op = std::make_unique<SparcOperand>(args: k_TailRelocSym);
523 Op->Imm.Val = Val;
524 Op->StartLoc = S;
525 Op->EndLoc = E;
526 return Op;
527 }
528
529 static bool MorphToIntPairReg(SparcOperand &Op) {
530 MCRegister Reg = Op.getReg();
531 assert(Op.Reg.Kind == rk_IntReg);
532 unsigned regIdx = 32;
533 if (Reg >= Sparc::G0 && Reg <= Sparc::G7)
534 regIdx = Reg - Sparc::G0;
535 else if (Reg >= Sparc::O0 && Reg <= Sparc::O7)
536 regIdx = Reg - Sparc::O0 + 8;
537 else if (Reg >= Sparc::L0 && Reg <= Sparc::L7)
538 regIdx = Reg - Sparc::L0 + 16;
539 else if (Reg >= Sparc::I0 && Reg <= Sparc::I7)
540 regIdx = Reg - Sparc::I0 + 24;
541 if (regIdx % 2 || regIdx > 31)
542 return false;
543 Op.Reg.RegNum = IntPairRegs[regIdx / 2];
544 Op.Reg.Kind = rk_IntPairReg;
545 return true;
546 }
547
548 static bool MorphToDoubleReg(SparcOperand &Op) {
549 MCRegister Reg = Op.getReg();
550 assert(Op.Reg.Kind == rk_FloatReg);
551 unsigned regIdx = Reg - Sparc::F0;
552 if (regIdx % 2 || regIdx > 31)
553 return false;
554 Op.Reg.RegNum = DoubleRegs[regIdx / 2];
555 Op.Reg.Kind = rk_DoubleReg;
556 return true;
557 }
558
559 static bool MorphToQuadReg(SparcOperand &Op) {
560 MCRegister Reg = Op.getReg();
561 unsigned regIdx = 0;
562 switch (Op.Reg.Kind) {
563 default: llvm_unreachable("Unexpected register kind!");
564 case rk_FloatReg:
565 regIdx = Reg - Sparc::F0;
566 if (regIdx % 4 || regIdx > 31)
567 return false;
568 Reg = QuadFPRegs[regIdx / 4];
569 break;
570 case rk_DoubleReg:
571 regIdx = Reg - Sparc::D0;
572 if (regIdx % 2 || regIdx > 31)
573 return false;
574 Reg = QuadFPRegs[regIdx / 2];
575 break;
576 }
577 Op.Reg.RegNum = Reg;
578 Op.Reg.Kind = rk_QuadReg;
579 return true;
580 }
581
582 static bool MorphToCoprocPairReg(SparcOperand &Op) {
583 MCRegister Reg = Op.getReg();
584 assert(Op.Reg.Kind == rk_CoprocReg);
585 unsigned regIdx = 32;
586 if (Reg >= Sparc::C0 && Reg <= Sparc::C31)
587 regIdx = Reg - Sparc::C0;
588 if (regIdx % 2 || regIdx > 31)
589 return false;
590 Op.Reg.RegNum = CoprocPairRegs[regIdx / 2];
591 Op.Reg.Kind = rk_CoprocPairReg;
592 return true;
593 }
594
595 static std::unique_ptr<SparcOperand>
596 MorphToMEMrr(unsigned Base, std::unique_ptr<SparcOperand> Op) {
597 MCRegister offsetReg = Op->getReg();
598 Op->Kind = k_MemoryReg;
599 Op->Mem.Base = Base;
600 Op->Mem.OffsetReg = offsetReg;
601 Op->Mem.Off = nullptr;
602 return Op;
603 }
604
605 static std::unique_ptr<SparcOperand>
606 CreateMEMr(unsigned Base, SMLoc S, SMLoc E) {
607 auto Op = std::make_unique<SparcOperand>(args: k_MemoryReg);
608 Op->Mem.Base = Base;
609 Op->Mem.OffsetReg = Sparc::G0; // always 0
610 Op->Mem.Off = nullptr;
611 Op->StartLoc = S;
612 Op->EndLoc = E;
613 return Op;
614 }
615
616 static std::unique_ptr<SparcOperand>
617 MorphToMEMri(unsigned Base, std::unique_ptr<SparcOperand> Op) {
618 const MCExpr *Imm = Op->getImm();
619 Op->Kind = k_MemoryImm;
620 Op->Mem.Base = Base;
621 Op->Mem.OffsetReg = 0;
622 Op->Mem.Off = Imm;
623 return Op;
624 }
625};
626
627} // end anonymous namespace
628
629#define GET_MATCHER_IMPLEMENTATION
630#define GET_REGISTER_MATCHER
631#define GET_MNEMONIC_SPELL_CHECKER
632#include "SparcGenAsmMatcher.inc"
633
634// Use a custom function instead of the one from SparcGenAsmMatcher
635// so we can differentiate between unavailable and unknown instructions.
636SparcAsmParser::MatchResultTy
637SparcAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {
638 // Process all MnemonicAliases to remap the mnemonic.
639 applyMnemonicAliases(Mnemonic, Features: getAvailableFeatures(), VariantID);
640
641 // Find the appropriate table for this asm variant.
642 const MatchEntry *Start, *End;
643 switch (VariantID) {
644 default:
645 llvm_unreachable("invalid variant!");
646 case 0:
647 Start = std::begin(arr: MatchTable0);
648 End = std::end(arr: MatchTable0);
649 break;
650 }
651
652 // Search the table.
653 auto MnemonicRange = std::equal_range(first: Start, last: End, val: Mnemonic, comp: LessOpcode());
654
655 if (MnemonicRange.first == MnemonicRange.second)
656 return Match_MnemonicFail;
657
658 for (const MatchEntry *it = MnemonicRange.first, *ie = MnemonicRange.second;
659 it != ie; ++it) {
660 const FeatureBitset &RequiredFeatures =
661 FeatureBitsets[it->RequiredFeaturesIdx];
662 if ((getAvailableFeatures() & RequiredFeatures) == RequiredFeatures)
663 return Match_Success;
664 }
665 return Match_MissingFeature;
666}
667
668bool SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
669 SmallVectorImpl<MCInst> &Instructions) {
670 MCOperand MCRegOp = Inst.getOperand(i: 0);
671 MCOperand MCValOp = Inst.getOperand(i: 1);
672 assert(MCRegOp.isReg());
673 assert(MCValOp.isImm() || MCValOp.isExpr());
674
675 // the imm operand can be either an expression or an immediate.
676 bool IsImm = Inst.getOperand(i: 1).isImm();
677 int64_t RawImmValue = IsImm ? MCValOp.getImm() : 0;
678
679 // Allow either a signed or unsigned 32-bit immediate.
680 if (RawImmValue < -2147483648LL || RawImmValue > 4294967295LL) {
681 return Error(L: IDLoc,
682 Msg: "set: argument must be between -2147483648 and 4294967295");
683 }
684
685 // If the value was expressed as a large unsigned number, that's ok.
686 // We want to see if it "looks like" a small signed number.
687 int32_t ImmValue = RawImmValue;
688 // For 'set' you can't use 'or' with a negative operand on V9 because
689 // that would splat the sign bit across the upper half of the destination
690 // register, whereas 'set' is defined to zero the high 32 bits.
691 bool IsEffectivelyImm13 =
692 IsImm && ((is64Bit() ? 0 : -4096) <= ImmValue && ImmValue < 4096);
693 const MCExpr *ValExpr;
694 if (IsImm)
695 ValExpr = MCConstantExpr::create(Value: ImmValue, Ctx&: getContext());
696 else
697 ValExpr = MCValOp.getExpr();
698
699 MCOperand PrevReg = MCOperand::createReg(Reg: Sparc::G0);
700
701 // If not just a signed imm13 value, then either we use a 'sethi' with a
702 // following 'or', or a 'sethi' by itself if there are no more 1 bits.
703 // In either case, start with the 'sethi'.
704 if (!IsEffectivelyImm13) {
705 MCInst TmpInst;
706 const MCExpr *Expr = adjustPICRelocation(VK: ELF::R_SPARC_HI22, subExpr: ValExpr);
707 TmpInst.setLoc(IDLoc);
708 TmpInst.setOpcode(SP::SETHIi);
709 TmpInst.addOperand(Op: MCRegOp);
710 TmpInst.addOperand(Op: MCOperand::createExpr(Val: Expr));
711 Instructions.push_back(Elt: TmpInst);
712 PrevReg = MCRegOp;
713 }
714
715 // The low bits require touching in 3 cases:
716 // * A non-immediate value will always require both instructions.
717 // * An effectively imm13 value needs only an 'or' instruction.
718 // * Otherwise, an immediate that is not effectively imm13 requires the
719 // 'or' only if bits remain after clearing the 22 bits that 'sethi' set.
720 // If the low bits are known zeros, there's nothing to do.
721 // In the second case, and only in that case, must we NOT clear
722 // bits of the immediate value via the %lo() assembler function.
723 // Note also, the 'or' instruction doesn't mind a large value in the case
724 // where the operand to 'set' was 0xFFFFFzzz - it does exactly what you mean.
725 if (!IsImm || IsEffectivelyImm13 || (ImmValue & 0x3ff)) {
726 MCInst TmpInst;
727 const MCExpr *Expr;
728 if (IsEffectivelyImm13)
729 Expr = ValExpr;
730 else
731 Expr = adjustPICRelocation(VK: ELF::R_SPARC_LO10, subExpr: ValExpr);
732 TmpInst.setLoc(IDLoc);
733 TmpInst.setOpcode(SP::ORri);
734 TmpInst.addOperand(Op: MCRegOp);
735 TmpInst.addOperand(Op: PrevReg);
736 TmpInst.addOperand(Op: MCOperand::createExpr(Val: Expr));
737 Instructions.push_back(Elt: TmpInst);
738 }
739 return false;
740}
741
742bool SparcAsmParser::expandSETSW(MCInst &Inst, SMLoc IDLoc,
743 SmallVectorImpl<MCInst> &Instructions) {
744 MCOperand MCRegOp = Inst.getOperand(i: 0);
745 MCOperand MCValOp = Inst.getOperand(i: 1);
746 assert(MCRegOp.isReg());
747 assert(MCValOp.isImm() || MCValOp.isExpr());
748
749 // The imm operand can be either an expression or an immediate.
750 bool IsImm = Inst.getOperand(i: 1).isImm();
751 int64_t ImmValue = IsImm ? MCValOp.getImm() : 0;
752 const MCExpr *ValExpr = IsImm ? MCConstantExpr::create(Value: ImmValue, Ctx&: getContext())
753 : MCValOp.getExpr();
754
755 bool IsSmallImm = IsImm && isInt<13>(x: ImmValue);
756 bool NoLowBitsImm = IsImm && ((ImmValue & 0x3FF) == 0);
757
758 MCOperand PrevReg = MCOperand::createReg(Reg: Sparc::G0);
759
760 if (!isInt<32>(x: ImmValue)) {
761 return Error(L: IDLoc,
762 Msg: "set: argument must be between -2147483648 and 2147483647");
763 }
764
765 // Very small immediates can be expressed without emitting a sethi.
766 if (!IsSmallImm) {
767 // sethi %hi(val), rd
768 Instructions.push_back(
769 Elt: MCInstBuilder(SP::SETHIi)
770 .addReg(Reg: MCRegOp.getReg())
771 .addExpr(Val: adjustPICRelocation(VK: ELF::R_SPARC_HI22, subExpr: ValExpr)));
772
773 PrevReg = MCRegOp;
774 }
775
776 // If the immediate has the lower bits set or is small, we need to emit an or.
777 if (!NoLowBitsImm || IsSmallImm) {
778 const MCExpr *Expr =
779 IsSmallImm ? ValExpr : adjustPICRelocation(VK: ELF::R_SPARC_LO10, subExpr: ValExpr);
780
781 // or rd, %lo(val), rd
782 Instructions.push_back(Elt: MCInstBuilder(SP::ORri)
783 .addReg(Reg: MCRegOp.getReg())
784 .addReg(Reg: PrevReg.getReg())
785 .addExpr(Val: Expr));
786
787 // If it's a small immediate there's nothing more to do.
788 if (IsSmallImm)
789 return false;
790 }
791
792 // Large negative or non-immediate expressions would need an sra.
793 if (!IsImm || ImmValue < 0) {
794 // sra rd, %g0, rd
795 Instructions.push_back(Elt: MCInstBuilder(SP::SRArr)
796 .addReg(Reg: MCRegOp.getReg())
797 .addReg(Reg: MCRegOp.getReg())
798 .addReg(Reg: Sparc::G0));
799 }
800
801 return false;
802}
803
804bool SparcAsmParser::expandSETX(MCInst &Inst, SMLoc IDLoc,
805 SmallVectorImpl<MCInst> &Instructions) {
806 MCOperand MCRegOp = Inst.getOperand(i: 0);
807 MCOperand MCValOp = Inst.getOperand(i: 1);
808 MCOperand MCTmpOp = Inst.getOperand(i: 2);
809 assert(MCRegOp.isReg() && MCTmpOp.isReg());
810 assert(MCValOp.isImm() || MCValOp.isExpr());
811
812 // the imm operand can be either an expression or an immediate.
813 bool IsImm = MCValOp.isImm();
814 int64_t ImmValue = IsImm ? MCValOp.getImm() : 0;
815
816 const MCExpr *ValExpr = IsImm ? MCConstantExpr::create(Value: ImmValue, Ctx&: getContext())
817 : MCValOp.getExpr();
818
819 // Very small immediates can be expressed directly as a single `or`.
820 if (IsImm && isInt<13>(x: ImmValue)) {
821 // or rd, val, rd
822 Instructions.push_back(Elt: MCInstBuilder(SP::ORri)
823 .addReg(Reg: MCRegOp.getReg())
824 .addReg(Reg: Sparc::G0)
825 .addExpr(Val: ValExpr));
826 return false;
827 }
828
829 // Otherwise, first we set the lower half of the register.
830
831 // sethi %hi(val), rd
832 Instructions.push_back(
833 Elt: MCInstBuilder(SP::SETHIi)
834 .addReg(Reg: MCRegOp.getReg())
835 .addExpr(Val: adjustPICRelocation(VK: ELF::R_SPARC_HI22, subExpr: ValExpr)));
836 // or rd, %lo(val), rd
837 Instructions.push_back(
838 Elt: MCInstBuilder(SP::ORri)
839 .addReg(Reg: MCRegOp.getReg())
840 .addReg(Reg: MCRegOp.getReg())
841 .addExpr(Val: adjustPICRelocation(VK: ELF::R_SPARC_LO10, subExpr: ValExpr)));
842
843 // Small positive immediates can be expressed as a single `sethi`+`or`
844 // combination, so we can just return here.
845 if (IsImm && isUInt<32>(x: ImmValue))
846 return false;
847
848 // For bigger immediates, we need to generate the upper half, then shift and
849 // merge it with the lower half that has just been generated above.
850
851 // sethi %hh(val), tmp
852 Instructions.push_back(Elt: MCInstBuilder(SP::SETHIi)
853 .addReg(Reg: MCTmpOp.getReg())
854 .addExpr(Val: MCSpecifierExpr::create(
855 Expr: ValExpr, S: ELF::R_SPARC_HH22, Ctx&: getContext())));
856 // or tmp, %hm(val), tmp
857 Instructions.push_back(Elt: MCInstBuilder(SP::ORri)
858 .addReg(Reg: MCTmpOp.getReg())
859 .addReg(Reg: MCTmpOp.getReg())
860 .addExpr(Val: MCSpecifierExpr::create(
861 Expr: ValExpr, S: ELF::R_SPARC_HM10, Ctx&: getContext())));
862 // sllx tmp, 32, tmp
863 Instructions.push_back(Elt: MCInstBuilder(SP::SLLXri)
864 .addReg(Reg: MCTmpOp.getReg())
865 .addReg(Reg: MCTmpOp.getReg())
866 .addImm(Val: 32));
867 // or tmp, rd, rd
868 Instructions.push_back(Elt: MCInstBuilder(SP::ORrr)
869 .addReg(Reg: MCRegOp.getReg())
870 .addReg(Reg: MCTmpOp.getReg())
871 .addReg(Reg: MCRegOp.getReg()));
872
873 return false;
874}
875
876bool SparcAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
877 OperandVector &Operands,
878 MCStreamer &Out,
879 uint64_t &ErrorInfo,
880 bool MatchingInlineAsm) {
881 MCInst Inst;
882 SmallVector<MCInst, 8> Instructions;
883 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
884 matchingInlineAsm: MatchingInlineAsm);
885 switch (MatchResult) {
886 case Match_Success: {
887 switch (Inst.getOpcode()) {
888 default:
889 Inst.setLoc(IDLoc);
890 Instructions.push_back(Elt: Inst);
891 break;
892 case SP::SET:
893 if (expandSET(Inst, IDLoc, Instructions))
894 return true;
895 break;
896 case SP::SETSW:
897 if (expandSETSW(Inst, IDLoc, Instructions))
898 return true;
899 break;
900 case SP::SETX:
901 if (expandSETX(Inst, IDLoc, Instructions))
902 return true;
903 break;
904 }
905
906 for (const MCInst &I : Instructions) {
907 Out.emitInstruction(Inst: I, STI: getSTI());
908 }
909 return false;
910 }
911
912 case Match_MissingFeature:
913 return Error(L: IDLoc,
914 Msg: "instruction requires a CPU feature not currently enabled");
915
916 case Match_InvalidOperand: {
917 SMLoc ErrorLoc = IDLoc;
918 if (ErrorInfo != ~0ULL) {
919 if (ErrorInfo >= Operands.size())
920 return Error(L: IDLoc, Msg: "too few operands for instruction");
921
922 ErrorLoc = ((SparcOperand &)*Operands[ErrorInfo]).getStartLoc();
923 if (ErrorLoc == SMLoc())
924 ErrorLoc = IDLoc;
925 }
926
927 return Error(L: ErrorLoc, Msg: "invalid operand for instruction");
928 }
929 case Match_MnemonicFail:
930 return Error(L: IDLoc, Msg: "invalid instruction mnemonic");
931 }
932 llvm_unreachable("Implement any new match types added!");
933}
934
935bool SparcAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
936 SMLoc &EndLoc) {
937 if (!tryParseRegister(Reg, StartLoc, EndLoc).isSuccess())
938 return Error(L: StartLoc, Msg: "invalid register name");
939 return false;
940}
941
942ParseStatus SparcAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
943 SMLoc &EndLoc) {
944 const AsmToken &Tok = Parser.getTok();
945 StartLoc = Tok.getLoc();
946 EndLoc = Tok.getEndLoc();
947 Reg = Sparc::NoRegister;
948 if (getLexer().getKind() != AsmToken::Percent)
949 return ParseStatus::NoMatch;
950 Parser.Lex();
951 unsigned RegKind = SparcOperand::rk_None;
952 Reg = matchRegisterName(Tok, RegKind);
953 if (Reg) {
954 Parser.Lex();
955 return ParseStatus::Success;
956 }
957
958 getLexer().UnLex(Token: Tok);
959 return ParseStatus::NoMatch;
960}
961
962bool SparcAsmParser::parseInstruction(ParseInstructionInfo &Info,
963 StringRef Name, SMLoc NameLoc,
964 OperandVector &Operands) {
965 // Validate and reject unavailable mnemonics early before
966 // running any operand parsing.
967 // This is needed because some operands (mainly memory ones)
968 // differ between V8 and V9 ISA and so any operand parsing errors
969 // will cause IAS to bail out before it reaches matchAndEmitInstruction
970 // (where the instruction as a whole, including the mnemonic, is validated
971 // once again just before emission).
972 // As a nice side effect this also allows us to reject unknown
973 // instructions and suggest replacements.
974 MatchResultTy MS = mnemonicIsValid(Mnemonic: Name, VariantID: 0);
975 switch (MS) {
976 case Match_Success:
977 break;
978 case Match_MissingFeature:
979 return Error(L: NameLoc,
980 Msg: "instruction requires a CPU feature not currently enabled");
981 case Match_MnemonicFail:
982 return Error(L: NameLoc,
983 Msg: "invalid instruction mnemonic" +
984 SparcMnemonicSpellCheck(S: Name, FBS: getAvailableFeatures(), VariantID: 0));
985 default:
986 llvm_unreachable("invalid return status!");
987 }
988
989 // First operand in MCInst is instruction mnemonic.
990 Operands.push_back(Elt: SparcOperand::CreateToken(Str: Name, S: NameLoc));
991
992 // apply mnemonic aliases, if any, so that we can parse operands correctly.
993 applyMnemonicAliases(Mnemonic&: Name, Features: getAvailableFeatures(), VariantID: 0);
994
995 if (getLexer().isNot(K: AsmToken::EndOfStatement)) {
996 // Read the first operand.
997 if (getLexer().is(K: AsmToken::Comma)) {
998 if (!parseBranchModifiers(Operands).isSuccess()) {
999 SMLoc Loc = getLexer().getLoc();
1000 return Error(L: Loc, Msg: "unexpected token");
1001 }
1002 }
1003 if (!parseOperand(Operands, Name).isSuccess()) {
1004 SMLoc Loc = getLexer().getLoc();
1005 return Error(L: Loc, Msg: "unexpected token");
1006 }
1007
1008 while (getLexer().is(K: AsmToken::Comma) || getLexer().is(K: AsmToken::Plus)) {
1009 if (getLexer().is(K: AsmToken::Plus)) {
1010 // Plus tokens are significant in software_traps (p83, sparcv8.pdf). We must capture them.
1011 Operands.push_back(Elt: SparcOperand::CreateToken(Str: "+", S: Parser.getTok().getLoc()));
1012 }
1013 Parser.Lex(); // Eat the comma or plus.
1014 // Parse and remember the operand.
1015 if (!parseOperand(Operands, Name).isSuccess()) {
1016 SMLoc Loc = getLexer().getLoc();
1017 return Error(L: Loc, Msg: "unexpected token");
1018 }
1019 }
1020 }
1021 if (getLexer().isNot(K: AsmToken::EndOfStatement)) {
1022 SMLoc Loc = getLexer().getLoc();
1023 return Error(L: Loc, Msg: "unexpected token");
1024 }
1025 Parser.Lex(); // Consume the EndOfStatement.
1026 return false;
1027}
1028
1029ParseStatus SparcAsmParser::parseDirective(AsmToken DirectiveID) {
1030 StringRef IDVal = DirectiveID.getString();
1031
1032 if (IDVal == ".register") {
1033 // For now, ignore .register directive.
1034 Parser.eatToEndOfStatement();
1035 return ParseStatus::Success;
1036 }
1037 if (IDVal == ".proc") {
1038 // For compatibility, ignore this directive.
1039 // (It's supposed to be an "optimization" in the Sun assembler)
1040 Parser.eatToEndOfStatement();
1041 return ParseStatus::Success;
1042 }
1043
1044 // Let the MC layer to handle other directives.
1045 return ParseStatus::NoMatch;
1046}
1047
1048ParseStatus SparcAsmParser::parseMEMOperand(OperandVector &Operands) {
1049 SMLoc S, E;
1050
1051 std::unique_ptr<SparcOperand> LHS;
1052 if (!parseSparcAsmOperand(Operand&: LHS).isSuccess())
1053 return ParseStatus::NoMatch;
1054
1055 // Single immediate operand
1056 if (LHS->isImm()) {
1057 Operands.push_back(Elt: SparcOperand::MorphToMEMri(Base: Sparc::G0, Op: std::move(LHS)));
1058 return ParseStatus::Success;
1059 }
1060
1061 if (!LHS->isIntReg())
1062 return Error(L: LHS->getStartLoc(), Msg: "invalid register kind for this operand");
1063
1064 AsmToken Tok = getLexer().getTok();
1065 // The plus token may be followed by a register or an immediate value, the
1066 // minus one is always interpreted as sign for the immediate value
1067 if (Tok.is(K: AsmToken::Plus) || Tok.is(K: AsmToken::Minus)) {
1068 (void)Parser.parseOptionalToken(T: AsmToken::Plus);
1069
1070 std::unique_ptr<SparcOperand> RHS;
1071 if (!parseSparcAsmOperand(Operand&: RHS).isSuccess())
1072 return ParseStatus::NoMatch;
1073
1074 if (RHS->isReg() && !RHS->isIntReg())
1075 return Error(L: RHS->getStartLoc(),
1076 Msg: "invalid register kind for this operand");
1077
1078 Operands.push_back(
1079 Elt: RHS->isImm()
1080 ? SparcOperand::MorphToMEMri(Base: LHS->getReg(), Op: std::move(RHS))
1081 : SparcOperand::MorphToMEMrr(Base: LHS->getReg(), Op: std::move(RHS)));
1082
1083 return ParseStatus::Success;
1084 }
1085
1086 Operands.push_back(Elt: SparcOperand::CreateMEMr(Base: LHS->getReg(), S, E));
1087 return ParseStatus::Success;
1088}
1089
1090template <unsigned N>
1091ParseStatus SparcAsmParser::parseShiftAmtImm(OperandVector &Operands) {
1092 SMLoc S = Parser.getTok().getLoc();
1093 SMLoc E = SMLoc::getFromPointer(Ptr: S.getPointer() - 1);
1094
1095 // This is a register, not an immediate
1096 if (getLexer().getKind() == AsmToken::Percent)
1097 return ParseStatus::NoMatch;
1098
1099 const MCExpr *Expr;
1100 if (getParser().parseExpression(Res&: Expr))
1101 return ParseStatus::Failure;
1102
1103 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Val: Expr);
1104 if (!CE)
1105 return Error(L: S, Msg: "constant expression expected");
1106
1107 if (!isUInt<N>(CE->getValue()))
1108 return Error(L: S, Msg: "immediate shift value out of range");
1109
1110 Operands.push_back(Elt: SparcOperand::CreateImm(Val: Expr, S, E));
1111 return ParseStatus::Success;
1112}
1113
1114template <SparcAsmParser::TailRelocKind Kind>
1115ParseStatus SparcAsmParser::parseTailRelocSym(OperandVector &Operands) {
1116 SMLoc S = getLoc();
1117 SMLoc E = SMLoc::getFromPointer(Ptr: S.getPointer() - 1);
1118
1119 auto MatchesKind = [](uint16_t RelType) -> bool {
1120 switch (Kind) {
1121 case TailRelocKind::Load_GOT:
1122 // Non-TLS relocations on ld (or ldx).
1123 // ld [%rr + %rr], %rr, %rel(sym)
1124 return RelType == ELF::R_SPARC_GOTDATA_OP;
1125 case TailRelocKind::Add_TLS:
1126 // TLS relocations on add.
1127 // add %rr, %rr, %rr, %rel(sym)
1128 switch (RelType) {
1129 case ELF::R_SPARC_TLS_GD_ADD:
1130 case ELF::R_SPARC_TLS_IE_ADD:
1131 case ELF::R_SPARC_TLS_LDM_ADD:
1132 case ELF::R_SPARC_TLS_LDO_ADD:
1133 return true;
1134 default:
1135 return false;
1136 }
1137 case TailRelocKind::Load_TLS:
1138 // TLS relocations on ld (or ldx).
1139 // ld[x] %addr, %rr, %rel(sym)
1140 switch (RelType) {
1141 case ELF::R_SPARC_TLS_IE_LD:
1142 case ELF::R_SPARC_TLS_IE_LDX:
1143 return true;
1144 default:
1145 return false;
1146 }
1147 case TailRelocKind::Call_TLS:
1148 // TLS relocations on call.
1149 // call sym, %rel(sym)
1150 switch (RelType) {
1151 case ELF::R_SPARC_TLS_GD_CALL:
1152 case ELF::R_SPARC_TLS_LDM_CALL:
1153 return true;
1154 default:
1155 return false;
1156 }
1157 }
1158 llvm_unreachable("Unhandled SparcAsmParser::TailRelocKind enum");
1159 };
1160
1161 if (getLexer().getKind() != AsmToken::Percent)
1162 return ParseStatus::NoMatch;
1163
1164 const AsmToken Tok = Parser.getTok();
1165 getParser().Lex(); // Eat '%'
1166
1167 if (getLexer().getKind() != AsmToken::Identifier)
1168 return Error(L: getLoc(), Msg: "expected valid identifier for operand modifier");
1169
1170 StringRef Name = getParser().getTok().getIdentifier();
1171 uint16_t RelType = Sparc::parseSpecifier(name: Name);
1172 if (RelType == 0)
1173 return Error(L: getLoc(), Msg: "invalid relocation specifier");
1174
1175 if (!MatchesKind(RelType)) {
1176 // Did not match the specified set of relocation types, put '%' back.
1177 getLexer().UnLex(Token: Tok);
1178 return ParseStatus::NoMatch;
1179 }
1180
1181 Parser.Lex(); // Eat the identifier.
1182 if (getLexer().getKind() != AsmToken::LParen)
1183 return Error(L: getLoc(), Msg: "expected '('");
1184
1185 getParser().Lex(); // Eat '('
1186 const MCExpr *SubExpr;
1187 if (getParser().parseParenExpression(Res&: SubExpr, EndLoc&: E))
1188 return ParseStatus::Failure;
1189
1190 const MCExpr *Val = adjustPICRelocation(VK: RelType, subExpr: SubExpr);
1191 Operands.push_back(Elt: SparcOperand::CreateTailRelocSym(Val, S, E));
1192 return ParseStatus::Success;
1193}
1194
1195ParseStatus SparcAsmParser::parseMembarTag(OperandVector &Operands) {
1196 SMLoc S = Parser.getTok().getLoc();
1197 const MCExpr *EVal;
1198 int64_t ImmVal = 0;
1199
1200 std::unique_ptr<SparcOperand> Mask;
1201 if (parseSparcAsmOperand(Operand&: Mask).isSuccess()) {
1202 if (!Mask->isImm() || !Mask->getImm()->evaluateAsAbsolute(Res&: ImmVal) ||
1203 ImmVal < 0 || ImmVal > 127)
1204 return Error(L: S, Msg: "invalid membar mask number");
1205 }
1206
1207 while (getLexer().getKind() == AsmToken::Hash) {
1208 SMLoc TagStart = getLexer().getLoc();
1209 Parser.Lex(); // Eat the '#'.
1210 unsigned MaskVal = StringSwitch<unsigned>(Parser.getTok().getString())
1211 .Case(S: "LoadLoad", Value: 0x1)
1212 .Case(S: "StoreLoad", Value: 0x2)
1213 .Case(S: "LoadStore", Value: 0x4)
1214 .Case(S: "StoreStore", Value: 0x8)
1215 .Case(S: "Lookaside", Value: 0x10)
1216 .Case(S: "MemIssue", Value: 0x20)
1217 .Case(S: "Sync", Value: 0x40)
1218 .Default(Value: 0);
1219
1220 Parser.Lex(); // Eat the identifier token.
1221
1222 if (!MaskVal)
1223 return Error(L: TagStart, Msg: "unknown membar tag");
1224
1225 ImmVal |= MaskVal;
1226
1227 if (getLexer().getKind() == AsmToken::Pipe)
1228 Parser.Lex(); // Eat the '|'.
1229 }
1230
1231 EVal = MCConstantExpr::create(Value: ImmVal, Ctx&: getContext());
1232 SMLoc E = SMLoc::getFromPointer(Ptr: Parser.getTok().getLoc().getPointer() - 1);
1233 Operands.push_back(Elt: SparcOperand::CreateImm(Val: EVal, S, E));
1234 return ParseStatus::Success;
1235}
1236
1237ParseStatus SparcAsmParser::parseASITag(OperandVector &Operands) {
1238 SMLoc S = Parser.getTok().getLoc();
1239 SMLoc E = Parser.getTok().getEndLoc();
1240 int64_t ASIVal = 0;
1241
1242 if (getLexer().getKind() != AsmToken::Hash) {
1243 // If the ASI tag provided is not a named tag, then it
1244 // must be a constant expression.
1245 ParseStatus ParseExprStatus = parseExpression(Val&: ASIVal);
1246 if (!ParseExprStatus.isSuccess())
1247 return ParseExprStatus;
1248
1249 if (!isUInt<8>(x: ASIVal))
1250 return Error(L: S, Msg: "invalid ASI number, must be between 0 and 255");
1251
1252 Operands.push_back(Elt: SparcOperand::CreateASITag(Val: ASIVal, S, E));
1253 return ParseStatus::Success;
1254 }
1255
1256 // For now we only support named tags for 64-bit/V9 systems.
1257 // TODO: add support for 32-bit/V8 systems.
1258 SMLoc TagStart = getLexer().peekTok(ShouldSkipSpace: false).getLoc();
1259 Parser.Lex(); // Eat the '#'.
1260 const StringRef ASIName = Parser.getTok().getString();
1261 const SparcASITag::ASITag *ASITag = SparcASITag::lookupASITagByName(Name: ASIName);
1262 if (!ASITag)
1263 ASITag = SparcASITag::lookupASITagByAltName(AltName: ASIName);
1264 Parser.Lex(); // Eat the identifier token.
1265
1266 if (!ASITag)
1267 return Error(L: TagStart, Msg: "unknown ASI tag");
1268
1269 ASIVal = ASITag->Encoding;
1270
1271 Operands.push_back(Elt: SparcOperand::CreateASITag(Val: ASIVal, S, E));
1272 return ParseStatus::Success;
1273}
1274
1275ParseStatus SparcAsmParser::parsePrefetchTag(OperandVector &Operands) {
1276 SMLoc S = Parser.getTok().getLoc();
1277 SMLoc E = Parser.getTok().getEndLoc();
1278 int64_t PrefetchVal = 0;
1279
1280 if (getLexer().getKind() != AsmToken::Hash) {
1281 // If the prefetch tag provided is not a named tag, then it
1282 // must be a constant expression.
1283 ParseStatus ParseExprStatus = parseExpression(Val&: PrefetchVal);
1284 if (!ParseExprStatus.isSuccess())
1285 return ParseExprStatus;
1286
1287 if (!isUInt<8>(x: PrefetchVal))
1288 return Error(L: S, Msg: "invalid prefetch number, must be between 0 and 31");
1289
1290 Operands.push_back(Elt: SparcOperand::CreatePrefetchTag(Val: PrefetchVal, S, E));
1291 return ParseStatus::Success;
1292 }
1293
1294 SMLoc TagStart = getLexer().peekTok(ShouldSkipSpace: false).getLoc();
1295 Parser.Lex(); // Eat the '#'.
1296 const StringRef PrefetchName = Parser.getTok().getString();
1297 const SparcPrefetchTag::PrefetchTag *PrefetchTag =
1298 SparcPrefetchTag::lookupPrefetchTagByName(Name: PrefetchName);
1299 Parser.Lex(); // Eat the identifier token.
1300
1301 if (!PrefetchTag)
1302 return Error(L: TagStart, Msg: "unknown prefetch tag");
1303
1304 PrefetchVal = PrefetchTag->Encoding;
1305
1306 Operands.push_back(Elt: SparcOperand::CreatePrefetchTag(Val: PrefetchVal, S, E));
1307 return ParseStatus::Success;
1308}
1309
1310ParseStatus SparcAsmParser::parseCallTarget(OperandVector &Operands) {
1311 SMLoc S = Parser.getTok().getLoc();
1312 SMLoc E = SMLoc::getFromPointer(Ptr: S.getPointer() - 1);
1313
1314 switch (getLexer().getKind()) {
1315 default:
1316 return ParseStatus::NoMatch;
1317 case AsmToken::LParen:
1318 case AsmToken::Integer:
1319 case AsmToken::Identifier:
1320 case AsmToken::Dot:
1321 break;
1322 }
1323
1324 const MCExpr *DestValue;
1325 if (getParser().parseExpression(Res&: DestValue))
1326 return ParseStatus::NoMatch;
1327
1328 Operands.push_back(Elt: SparcOperand::CreateImm(Val: DestValue, S, E));
1329 return ParseStatus::Success;
1330}
1331
1332ParseStatus SparcAsmParser::parseOperand(OperandVector &Operands,
1333 StringRef Mnemonic) {
1334
1335 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic);
1336
1337 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1338 // there was a match, but an error occurred, in which case, just return that
1339 // the operand parsing failed.
1340 if (Res.isSuccess() || Res.isFailure())
1341 return Res;
1342
1343 if (getLexer().is(K: AsmToken::LBrac)) {
1344 // Memory operand
1345 Operands.push_back(Elt: SparcOperand::CreateToken(Str: "[",
1346 S: Parser.getTok().getLoc()));
1347 Parser.Lex(); // Eat the [
1348
1349 if (Mnemonic == "cas" || Mnemonic == "casl" || Mnemonic == "casa" ||
1350 Mnemonic == "casx" || Mnemonic == "casxl" || Mnemonic == "casxa") {
1351 SMLoc S = Parser.getTok().getLoc();
1352 if (getLexer().getKind() != AsmToken::Percent)
1353 return ParseStatus::NoMatch;
1354 Parser.Lex(); // eat %
1355
1356 unsigned RegKind;
1357 MCRegister Reg = matchRegisterName(Tok: Parser.getTok(), RegKind);
1358 if (!Reg)
1359 return ParseStatus::NoMatch;
1360
1361 Parser.Lex(); // Eat the identifier token.
1362 SMLoc E = SMLoc::getFromPointer(Ptr: Parser.getTok().getLoc().getPointer()-1);
1363 Operands.push_back(Elt: SparcOperand::CreateReg(RegNum: Reg, Kind: RegKind, S, E));
1364 Res = ParseStatus::Success;
1365 } else {
1366 Res = parseMEMOperand(Operands);
1367 }
1368
1369 if (!Res.isSuccess())
1370 return Res;
1371
1372 if (!getLexer().is(K: AsmToken::RBrac))
1373 return ParseStatus::Failure;
1374
1375 Operands.push_back(Elt: SparcOperand::CreateToken(Str: "]",
1376 S: Parser.getTok().getLoc()));
1377 Parser.Lex(); // Eat the ]
1378
1379 // Parse an optional address-space identifier after the address.
1380 // This will be either an immediate constant expression, or, on 64-bit
1381 // processors, the %asi register.
1382 if (getLexer().is(K: AsmToken::Percent)) {
1383 SMLoc S = Parser.getTok().getLoc();
1384 if (!is64Bit())
1385 return Error(
1386 L: S, Msg: "malformed ASI tag, must be a constant integer expression");
1387
1388 Parser.Lex(); // Eat the %.
1389 const AsmToken Tok = Parser.getTok();
1390 if (Tok.is(K: AsmToken::Identifier) && Tok.getString() == "asi") {
1391 // Here we patch the MEM operand from [base + %g0] into [base + 0]
1392 // as memory operations with ASI tag stored in %asi register needs
1393 // to use immediate offset. We need to do this because Reg addressing
1394 // will be parsed as Reg+G0 initially.
1395 // This allows forms such as `ldxa [%o0] %asi, %o0` to parse correctly.
1396 SparcOperand &OldMemOp = (SparcOperand &)*Operands[Operands.size() - 2];
1397 if (OldMemOp.isMEMrr()) {
1398 if (OldMemOp.getMemOffsetReg() != Sparc::G0) {
1399 return Error(L: S, Msg: "invalid operand for instruction");
1400 }
1401 Operands[Operands.size() - 2] = SparcOperand::MorphToMEMri(
1402 Base: OldMemOp.getMemBase(),
1403 Op: SparcOperand::CreateImm(Val: MCConstantExpr::create(Value: 0, Ctx&: getContext()),
1404 S: OldMemOp.getStartLoc(),
1405 E: OldMemOp.getEndLoc()));
1406 }
1407 Parser.Lex(); // Eat the identifier.
1408 // In this context, we convert the register operand into
1409 // a plain "%asi" token since the register access is already
1410 // implicit in the instruction definition and encoding.
1411 // See LoadASI/StoreASI in SparcInstrInfo.td.
1412 Operands.push_back(Elt: SparcOperand::CreateToken(Str: "%asi", S));
1413 return ParseStatus::Success;
1414 }
1415
1416 return Error(L: S, Msg: "malformed ASI tag, must be %asi, a constant integer "
1417 "expression, or a named tag");
1418 }
1419
1420 // If we're not at the end of statement and the next token is not a comma,
1421 // then it is an immediate ASI value.
1422 if (getLexer().isNot(K: AsmToken::EndOfStatement) &&
1423 getLexer().isNot(K: AsmToken::Comma))
1424 return parseASITag(Operands);
1425 return ParseStatus::Success;
1426 }
1427
1428 std::unique_ptr<SparcOperand> Op;
1429
1430 Res = parseSparcAsmOperand(Operand&: Op);
1431 if (!Res.isSuccess() || !Op)
1432 return ParseStatus::Failure;
1433
1434 // Push the parsed operand into the list of operands
1435 Operands.push_back(Elt: std::move(Op));
1436
1437 return ParseStatus::Success;
1438}
1439
1440ParseStatus
1441SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op) {
1442 SMLoc S = Parser.getTok().getLoc();
1443 SMLoc E = SMLoc::getFromPointer(Ptr: Parser.getTok().getLoc().getPointer() - 1);
1444 const MCExpr *EVal;
1445
1446 Op = nullptr;
1447 switch (getLexer().getKind()) {
1448 default: break;
1449
1450 case AsmToken::Percent: {
1451 Parser.Lex(); // Eat the '%'.
1452 unsigned RegKind;
1453 if (MCRegister Reg = matchRegisterName(Tok: Parser.getTok(), RegKind)) {
1454 StringRef Name = Parser.getTok().getString();
1455 Parser.Lex(); // Eat the identifier token.
1456 E = SMLoc::getFromPointer(Ptr: Parser.getTok().getLoc().getPointer() - 1);
1457 if (Reg == Sparc::ICC && Name == "xcc")
1458 Op = SparcOperand::CreateToken(Str: "%xcc", S);
1459 else
1460 Op = SparcOperand::CreateReg(RegNum: Reg, Kind: RegKind, S, E);
1461 break;
1462 }
1463 if (matchSparcAsmModifiers(EVal, EndLoc&: E)) {
1464 E = SMLoc::getFromPointer(Ptr: Parser.getTok().getLoc().getPointer() - 1);
1465 Op = SparcOperand::CreateImm(Val: EVal, S, E);
1466 }
1467 break;
1468 }
1469
1470 case AsmToken::Plus:
1471 case AsmToken::Minus:
1472 case AsmToken::Integer:
1473 case AsmToken::LParen:
1474 case AsmToken::Dot:
1475 case AsmToken::Identifier:
1476 if (getParser().parseExpression(Res&: EVal, EndLoc&: E))
1477 break;
1478
1479 Op = SparcOperand::CreateImm(Val: EVal, S, E);
1480 break;
1481 }
1482 return Op ? ParseStatus::Success : ParseStatus::Failure;
1483}
1484
1485ParseStatus SparcAsmParser::parseBranchModifiers(OperandVector &Operands) {
1486 // parse (,a|,pn|,pt)+
1487
1488 while (getLexer().is(K: AsmToken::Comma)) {
1489 Parser.Lex(); // Eat the comma
1490
1491 if (!getLexer().is(K: AsmToken::Identifier))
1492 return ParseStatus::Failure;
1493 StringRef modName = Parser.getTok().getString();
1494 if (modName == "a" || modName == "pn" || modName == "pt") {
1495 Operands.push_back(Elt: SparcOperand::CreateToken(Str: modName,
1496 S: Parser.getTok().getLoc()));
1497 Parser.Lex(); // eat the identifier.
1498 }
1499 }
1500 return ParseStatus::Success;
1501}
1502
1503ParseStatus SparcAsmParser::parseExpression(int64_t &Val) {
1504 AsmToken Tok = getLexer().getTok();
1505
1506 if (!isPossibleExpression(Token: Tok))
1507 return ParseStatus::NoMatch;
1508
1509 return getParser().parseAbsoluteExpression(Res&: Val);
1510}
1511
1512MCRegister SparcAsmParser::matchRegisterName(const AsmToken &Tok,
1513 unsigned &RegKind) {
1514 RegKind = SparcOperand::rk_None;
1515 if (!Tok.is(K: AsmToken::Identifier))
1516 return SP::NoRegister;
1517
1518 StringRef Name = Tok.getString();
1519 MCRegister Reg = MatchRegisterName(Name: Name.lower());
1520 if (!Reg)
1521 Reg = MatchRegisterAltName(Name: Name.lower());
1522
1523 if (Reg) {
1524 // Some registers have identical spellings. The generated matcher might
1525 // have chosen one or another spelling, e.g. "%fp" or "%i6" might have been
1526 // matched to either SP::I6 or SP::I6_I7. Other parts of SparcAsmParser
1527 // are not prepared for this, so we do some canonicalization.
1528
1529 // See the note in SparcRegisterInfo.td near ASRRegs register class.
1530 if (Reg == SP::ASR4 && Name == "tick") {
1531 RegKind = SparcOperand::rk_Special;
1532 return SP::TICK;
1533 }
1534
1535 if (MRI.getRegClass(i: SP::IntRegsRegClassID).contains(Reg)) {
1536 RegKind = SparcOperand::rk_IntReg;
1537 return Reg;
1538 }
1539 if (MRI.getRegClass(i: SP::FPRegsRegClassID).contains(Reg)) {
1540 RegKind = SparcOperand::rk_FloatReg;
1541 return Reg;
1542 }
1543 if (MRI.getRegClass(i: SP::CoprocRegsRegClassID).contains(Reg)) {
1544 RegKind = SparcOperand::rk_CoprocReg;
1545 return Reg;
1546 }
1547
1548 // Canonicalize G0_G1 ... G30_G31 etc. to G0 ... G30.
1549 if (MRI.getRegClass(i: SP::IntPairRegClassID).contains(Reg)) {
1550 RegKind = SparcOperand::rk_IntReg;
1551 return MRI.getSubReg(Reg, Idx: SP::sub_even);
1552 }
1553
1554 // Canonicalize D0 ... D15 to F0 ... F30.
1555 if (MRI.getRegClass(i: SP::DFPRegsRegClassID).contains(Reg)) {
1556 // D16 ... D31 do not have sub-registers.
1557 if (MCRegister SubReg = MRI.getSubReg(Reg, Idx: SP::sub_even)) {
1558 RegKind = SparcOperand::rk_FloatReg;
1559 return SubReg;
1560 }
1561 RegKind = SparcOperand::rk_DoubleReg;
1562 return Reg;
1563 }
1564
1565 // The generated matcher does not currently return QFP registers.
1566 // If it changes, we will need to handle them in a similar way.
1567 assert(!MRI.getRegClass(SP::QFPRegsRegClassID).contains(Reg));
1568
1569 // Canonicalize C0_C1 ... C30_C31 to C0 ... C30.
1570 if (MRI.getRegClass(i: SP::CoprocPairRegClassID).contains(Reg)) {
1571 RegKind = SparcOperand::rk_CoprocReg;
1572 return MRI.getSubReg(Reg, Idx: SP::sub_even);
1573 }
1574
1575 // Other registers do not need special handling.
1576 RegKind = SparcOperand::rk_Special;
1577 return Reg;
1578 }
1579
1580 // If we still have no match, try custom parsing.
1581 // Not all registers and their spellings are modeled in td files.
1582
1583 // %r0 - %r31
1584 int64_t RegNo = 0;
1585 if (Name.starts_with_insensitive(Prefix: "r") &&
1586 !Name.substr(Start: 1, N: 2).getAsInteger(Radix: 10, Result&: RegNo) && RegNo < 31) {
1587 RegKind = SparcOperand::rk_IntReg;
1588 return IntRegs[RegNo];
1589 }
1590
1591 if (Name == "xcc") {
1592 // FIXME:: check 64bit.
1593 RegKind = SparcOperand::rk_Special;
1594 return SP::ICC;
1595 }
1596
1597 // JPS1 extension - aliases for ASRs
1598 // Section 5.2.11 - Ancillary State Registers (ASRs)
1599 if (Name == "pcr") {
1600 RegKind = SparcOperand::rk_Special;
1601 return SP::ASR16;
1602 }
1603 if (Name == "pic") {
1604 RegKind = SparcOperand::rk_Special;
1605 return SP::ASR17;
1606 }
1607 if (Name == "dcr") {
1608 RegKind = SparcOperand::rk_Special;
1609 return SP::ASR18;
1610 }
1611 if (Name == "gsr") {
1612 RegKind = SparcOperand::rk_Special;
1613 return SP::ASR19;
1614 }
1615 if (Name == "set_softint") {
1616 RegKind = SparcOperand::rk_Special;
1617 return SP::ASR20;
1618 }
1619 if (Name == "clear_softint") {
1620 RegKind = SparcOperand::rk_Special;
1621 return SP::ASR21;
1622 }
1623 if (Name == "softint") {
1624 RegKind = SparcOperand::rk_Special;
1625 return SP::ASR22;
1626 }
1627 if (Name == "tick_cmpr") {
1628 RegKind = SparcOperand::rk_Special;
1629 return SP::ASR23;
1630 }
1631 if (Name == "stick" || Name == "sys_tick") {
1632 RegKind = SparcOperand::rk_Special;
1633 return SP::ASR24;
1634 }
1635 if (Name == "stick_cmpr" || Name == "sys_tick_cmpr") {
1636 RegKind = SparcOperand::rk_Special;
1637 return SP::ASR25;
1638 }
1639
1640 return SP::NoRegister;
1641}
1642
1643// Determine if an expression contains a reference to the symbol
1644// "_GLOBAL_OFFSET_TABLE_".
1645static bool hasGOTReference(const MCExpr *Expr) {
1646 switch (Expr->getKind()) {
1647 case MCExpr::Target:
1648 if (const MCSpecifierExpr *SE = dyn_cast<MCSpecifierExpr>(Val: Expr))
1649 return hasGOTReference(Expr: SE->getSubExpr());
1650 break;
1651
1652 case MCExpr::Constant:
1653 break;
1654
1655 case MCExpr::Binary: {
1656 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Val: Expr);
1657 return hasGOTReference(Expr: BE->getLHS()) || hasGOTReference(Expr: BE->getRHS());
1658 }
1659
1660 case MCExpr::SymbolRef: {
1661 const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Val: Expr);
1662 return (SymRef.getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_");
1663 }
1664
1665 case MCExpr::Unary:
1666 return hasGOTReference(Expr: cast<MCUnaryExpr>(Val: Expr)->getSubExpr());
1667
1668 case MCExpr::Specifier:
1669 llvm_unreachable("unused by this backend");
1670 }
1671 return false;
1672}
1673
1674const MCSpecifierExpr *
1675SparcAsmParser::adjustPICRelocation(uint16_t RelType, const MCExpr *subExpr) {
1676 // When in PIC mode, "%lo(...)" and "%hi(...)" behave differently.
1677 // If the expression refers contains _GLOBAL_OFFSET_TABLE, it is
1678 // actually a %pc10 or %pc22 relocation. Otherwise, they are interpreted
1679 // as %got10 or %got22 relocation.
1680
1681 if (getContext().getObjectFileInfo()->isPositionIndependent()) {
1682 switch (RelType) {
1683 default: break;
1684 case ELF::R_SPARC_LO10:
1685 RelType =
1686 hasGOTReference(Expr: subExpr) ? ELF::R_SPARC_PC10 : ELF::R_SPARC_GOT10;
1687 break;
1688 case ELF::R_SPARC_HI22:
1689 RelType =
1690 hasGOTReference(Expr: subExpr) ? ELF::R_SPARC_PC22 : ELF::R_SPARC_GOT22;
1691 break;
1692 }
1693 }
1694
1695 return MCSpecifierExpr::create(Expr: subExpr, S: RelType, Ctx&: getContext());
1696}
1697
1698bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
1699 SMLoc &EndLoc) {
1700 AsmToken Tok = Parser.getTok();
1701 if (!Tok.is(K: AsmToken::Identifier))
1702 return false;
1703
1704 StringRef name = Tok.getString();
1705
1706 auto VK = Sparc::parseSpecifier(name);
1707 switch (VK) {
1708 case 0:
1709 Error(L: getLoc(), Msg: "invalid relocation specifier");
1710 return false;
1711
1712 case ELF::R_SPARC_GOTDATA_OP:
1713 case ELF::R_SPARC_TLS_GD_ADD:
1714 case ELF::R_SPARC_TLS_GD_CALL:
1715 case ELF::R_SPARC_TLS_IE_ADD:
1716 case ELF::R_SPARC_TLS_IE_LD:
1717 case ELF::R_SPARC_TLS_IE_LDX:
1718 case ELF::R_SPARC_TLS_LDM_ADD:
1719 case ELF::R_SPARC_TLS_LDM_CALL:
1720 case ELF::R_SPARC_TLS_LDO_ADD:
1721 // These are special-cased at tablegen level.
1722 return false;
1723
1724 default:
1725 break;
1726 }
1727
1728 Parser.Lex(); // Eat the identifier.
1729 if (Parser.getTok().getKind() != AsmToken::LParen)
1730 return false;
1731
1732 Parser.Lex(); // Eat the LParen token.
1733 const MCExpr *subExpr;
1734 if (Parser.parseParenExpression(Res&: subExpr, EndLoc))
1735 return false;
1736
1737 EVal = adjustPICRelocation(RelType: VK, subExpr);
1738 return true;
1739}
1740
1741bool SparcAsmParser::isPossibleExpression(const AsmToken &Token) {
1742 switch (Token.getKind()) {
1743 case AsmToken::LParen:
1744 case AsmToken::Integer:
1745 case AsmToken::Identifier:
1746 case AsmToken::Plus:
1747 case AsmToken::Minus:
1748 case AsmToken::Tilde:
1749 return true;
1750 default:
1751 return false;
1752 }
1753}
1754
1755extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
1756LLVMInitializeSparcAsmParser() {
1757 RegisterMCAsmParser<SparcAsmParser> A(getTheSparcTarget());
1758 RegisterMCAsmParser<SparcAsmParser> B(getTheSparcV9Target());
1759 RegisterMCAsmParser<SparcAsmParser> C(getTheSparcelTarget());
1760}
1761
1762unsigned SparcAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,
1763 unsigned Kind) {
1764 SparcOperand &Op = (SparcOperand &)GOp;
1765 if (Op.isFloatOrDoubleReg()) {
1766 switch (Kind) {
1767 default: break;
1768 case MCK_DFPRegs:
1769 if (!Op.isFloatReg() || SparcOperand::MorphToDoubleReg(Op))
1770 return MCTargetAsmParser::Match_Success;
1771 break;
1772 case MCK_QFPRegs:
1773 if (SparcOperand::MorphToQuadReg(Op))
1774 return MCTargetAsmParser::Match_Success;
1775 break;
1776 }
1777 }
1778 if (Op.isIntReg() && Kind == MCK_IntPair) {
1779 if (SparcOperand::MorphToIntPairReg(Op))
1780 return MCTargetAsmParser::Match_Success;
1781 }
1782 if (Op.isCoprocReg() && Kind == MCK_CoprocPair) {
1783 if (SparcOperand::MorphToCoprocPairReg(Op))
1784 return MCTargetAsmParser::Match_Success;
1785 }
1786 return Match_InvalidOperand;
1787}
1788