Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / lib / Target / Sparc / AsmParser / SparcAsmParser.cpp
blob54a7d92144568f2525635078d3cc39cc98a40ea9
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 //===----------------------------------------------------------------------===//
9 #include "MCTargetDesc/SparcMCExpr.h"
10 #include "MCTargetDesc/SparcMCTargetDesc.h"
11 #include "TargetInfo/SparcTargetInfo.h"
12 #include "llvm/ADT/STLExtras.h"
13 #include "llvm/ADT/SmallVector.h"
14 #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"
19 #include "llvm/MC/MCInstBuilder.h"
20 #include "llvm/MC/MCInstrInfo.h"
21 #include "llvm/MC/MCObjectFileInfo.h"
22 #include "llvm/MC/MCParser/MCAsmLexer.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/ErrorHandling.h"
33 #include "llvm/Support/MathExtras.h"
34 #include "llvm/Support/SMLoc.h"
35 #include "llvm/Support/raw_ostream.h"
36 #include "llvm/TargetParser/Triple.h"
37 #include <algorithm>
38 #include <cassert>
39 #include <cstdint>
40 #include <memory>
42 using namespace llvm;
44 // The generated AsmMatcher SparcGenAsmMatcher uses "Sparc" as the target
45 // namespace. But SPARC backend uses "SP" as its namespace.
46 namespace llvm {
47 namespace Sparc {
49 using namespace SP;
51 } // end namespace Sparc
52 } // end namespace llvm
54 namespace {
56 class SparcOperand;
58 class SparcAsmParser : public MCTargetAsmParser {
59 MCAsmParser &Parser;
61 enum class TailRelocKind { Load_GOT, Add_TLS, Load_TLS, Call_TLS };
63 /// @name Auto-generated Match Functions
64 /// {
66 #define GET_ASSEMBLER_HEADER
67 #include "SparcGenAsmMatcher.inc"
69 /// }
71 // public interface of the MCTargetAsmParser.
72 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
73 OperandVector &Operands, MCStreamer &Out,
74 uint64_t &ErrorInfo,
75 bool MatchingInlineAsm) override;
76 bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
77 ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
78 SMLoc &EndLoc) override;
79 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
80 SMLoc NameLoc, OperandVector &Operands) override;
81 ParseStatus parseDirective(AsmToken DirectiveID) override;
83 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
84 unsigned Kind) override;
86 // Custom parse functions for Sparc specific operands.
87 ParseStatus parseMEMOperand(OperandVector &Operands);
89 ParseStatus parseMembarTag(OperandVector &Operands);
91 ParseStatus parseASITag(OperandVector &Operands);
93 template <TailRelocKind Kind>
94 ParseStatus parseTailRelocSym(OperandVector &Operands);
96 template <unsigned N> ParseStatus parseShiftAmtImm(OperandVector &Operands);
98 ParseStatus parseCallTarget(OperandVector &Operands);
100 ParseStatus parseOperand(OperandVector &Operands, StringRef Name);
102 ParseStatus parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Operand,
103 bool isCall = false);
105 ParseStatus parseBranchModifiers(OperandVector &Operands);
107 // Helper function for dealing with %lo / %hi in PIC mode.
108 const SparcMCExpr *adjustPICRelocation(SparcMCExpr::VariantKind VK,
109 const MCExpr *subExpr);
111 // returns true if Tok is matched to a register and returns register in RegNo.
112 bool matchRegisterName(const AsmToken &Tok, MCRegister &RegNo,
113 unsigned &RegKind);
115 bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc);
117 bool is64Bit() const {
118 return getSTI().getTargetTriple().getArch() == Triple::sparcv9;
121 bool expandSET(MCInst &Inst, SMLoc IDLoc,
122 SmallVectorImpl<MCInst> &Instructions);
124 bool expandSETX(MCInst &Inst, SMLoc IDLoc,
125 SmallVectorImpl<MCInst> &Instructions);
127 SMLoc getLoc() const { return getParser().getTok().getLoc(); }
129 public:
130 SparcAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
131 const MCInstrInfo &MII,
132 const MCTargetOptions &Options)
133 : MCTargetAsmParser(Options, sti, MII), Parser(parser) {
134 Parser.addAliasForDirective(".half", ".2byte");
135 Parser.addAliasForDirective(".uahalf", ".2byte");
136 Parser.addAliasForDirective(".word", ".4byte");
137 Parser.addAliasForDirective(".uaword", ".4byte");
138 Parser.addAliasForDirective(".nword", is64Bit() ? ".8byte" : ".4byte");
139 if (is64Bit())
140 Parser.addAliasForDirective(".xword", ".8byte");
142 // Initialize the set of available features.
143 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
147 } // end anonymous namespace
149 static const MCPhysReg IntRegs[32] = {
150 Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,
151 Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,
152 Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,
153 Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,
154 Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,
155 Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,
156 Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,
157 Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };
159 static const MCPhysReg FloatRegs[32] = {
160 Sparc::F0, Sparc::F1, Sparc::F2, Sparc::F3,
161 Sparc::F4, Sparc::F5, Sparc::F6, Sparc::F7,
162 Sparc::F8, Sparc::F9, Sparc::F10, Sparc::F11,
163 Sparc::F12, Sparc::F13, Sparc::F14, Sparc::F15,
164 Sparc::F16, Sparc::F17, Sparc::F18, Sparc::F19,
165 Sparc::F20, Sparc::F21, Sparc::F22, Sparc::F23,
166 Sparc::F24, Sparc::F25, Sparc::F26, Sparc::F27,
167 Sparc::F28, Sparc::F29, Sparc::F30, Sparc::F31 };
169 static const MCPhysReg DoubleRegs[32] = {
170 Sparc::D0, Sparc::D1, Sparc::D2, Sparc::D3,
171 Sparc::D4, Sparc::D5, Sparc::D6, Sparc::D7,
172 Sparc::D8, Sparc::D9, Sparc::D10, Sparc::D11,
173 Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,
174 Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,
175 Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,
176 Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,
177 Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };
179 static const MCPhysReg QuadFPRegs[32] = {
180 Sparc::Q0, Sparc::Q1, Sparc::Q2, Sparc::Q3,
181 Sparc::Q4, Sparc::Q5, Sparc::Q6, Sparc::Q7,
182 Sparc::Q8, Sparc::Q9, Sparc::Q10, Sparc::Q11,
183 Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
185 static const MCPhysReg ASRRegs[32] = {
186 SP::Y, SP::ASR1, SP::ASR2, SP::ASR3,
187 SP::ASR4, SP::ASR5, SP::ASR6, SP::ASR7,
188 SP::ASR8, SP::ASR9, SP::ASR10, SP::ASR11,
189 SP::ASR12, SP::ASR13, SP::ASR14, SP::ASR15,
190 SP::ASR16, SP::ASR17, SP::ASR18, SP::ASR19,
191 SP::ASR20, SP::ASR21, SP::ASR22, SP::ASR23,
192 SP::ASR24, SP::ASR25, SP::ASR26, SP::ASR27,
193 SP::ASR28, SP::ASR29, SP::ASR30, SP::ASR31};
195 static const MCPhysReg IntPairRegs[] = {
196 Sparc::G0_G1, Sparc::G2_G3, Sparc::G4_G5, Sparc::G6_G7,
197 Sparc::O0_O1, Sparc::O2_O3, Sparc::O4_O5, Sparc::O6_O7,
198 Sparc::L0_L1, Sparc::L2_L3, Sparc::L4_L5, Sparc::L6_L7,
199 Sparc::I0_I1, Sparc::I2_I3, Sparc::I4_I5, Sparc::I6_I7};
201 static const MCPhysReg CoprocRegs[32] = {
202 Sparc::C0, Sparc::C1, Sparc::C2, Sparc::C3,
203 Sparc::C4, Sparc::C5, Sparc::C6, Sparc::C7,
204 Sparc::C8, Sparc::C9, Sparc::C10, Sparc::C11,
205 Sparc::C12, Sparc::C13, Sparc::C14, Sparc::C15,
206 Sparc::C16, Sparc::C17, Sparc::C18, Sparc::C19,
207 Sparc::C20, Sparc::C21, Sparc::C22, Sparc::C23,
208 Sparc::C24, Sparc::C25, Sparc::C26, Sparc::C27,
209 Sparc::C28, Sparc::C29, Sparc::C30, Sparc::C31 };
211 static const MCPhysReg CoprocPairRegs[] = {
212 Sparc::C0_C1, Sparc::C2_C3, Sparc::C4_C5, Sparc::C6_C7,
213 Sparc::C8_C9, Sparc::C10_C11, Sparc::C12_C13, Sparc::C14_C15,
214 Sparc::C16_C17, Sparc::C18_C19, Sparc::C20_C21, Sparc::C22_C23,
215 Sparc::C24_C25, Sparc::C26_C27, Sparc::C28_C29, Sparc::C30_C31};
217 namespace {
219 /// SparcOperand - Instances of this class represent a parsed Sparc machine
220 /// instruction.
221 class SparcOperand : public MCParsedAsmOperand {
222 public:
223 enum RegisterKind {
224 rk_None,
225 rk_IntReg,
226 rk_IntPairReg,
227 rk_FloatReg,
228 rk_DoubleReg,
229 rk_QuadReg,
230 rk_CoprocReg,
231 rk_CoprocPairReg,
232 rk_Special,
235 private:
236 enum KindTy {
237 k_Token,
238 k_Register,
239 k_Immediate,
240 k_MemoryReg,
241 k_MemoryImm,
242 k_ASITag
243 } Kind;
245 SMLoc StartLoc, EndLoc;
247 struct Token {
248 const char *Data;
249 unsigned Length;
252 struct RegOp {
253 unsigned RegNum;
254 RegisterKind Kind;
257 struct ImmOp {
258 const MCExpr *Val;
261 struct MemOp {
262 unsigned Base;
263 unsigned OffsetReg;
264 const MCExpr *Off;
267 union {
268 struct Token Tok;
269 struct RegOp Reg;
270 struct ImmOp Imm;
271 struct MemOp Mem;
272 unsigned ASI;
275 public:
276 SparcOperand(KindTy K) : Kind(K) {}
278 bool isToken() const override { return Kind == k_Token; }
279 bool isReg() const override { return Kind == k_Register; }
280 bool isImm() const override { return Kind == k_Immediate; }
281 bool isMem() const override { return isMEMrr() || isMEMri(); }
282 bool isMEMrr() const { return Kind == k_MemoryReg; }
283 bool isMEMri() const { return Kind == k_MemoryImm; }
284 bool isMembarTag() const { return Kind == k_Immediate; }
285 bool isASITag() const { return Kind == k_ASITag; }
286 bool isTailRelocSym() const { return Kind == k_Immediate; }
288 bool isCallTarget() const {
289 if (!isImm())
290 return false;
292 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val))
293 return CE->getValue() % 4 == 0;
295 return true;
298 bool isShiftAmtImm5() const {
299 if (!isImm())
300 return false;
302 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val))
303 return isUInt<5>(CE->getValue());
305 return false;
308 bool isShiftAmtImm6() const {
309 if (!isImm())
310 return false;
312 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val))
313 return isUInt<6>(CE->getValue());
315 return false;
318 bool isIntReg() const {
319 return (Kind == k_Register && Reg.Kind == rk_IntReg);
322 bool isFloatReg() const {
323 return (Kind == k_Register && Reg.Kind == rk_FloatReg);
326 bool isFloatOrDoubleReg() const {
327 return (Kind == k_Register && (Reg.Kind == rk_FloatReg
328 || Reg.Kind == rk_DoubleReg));
331 bool isCoprocReg() const {
332 return (Kind == k_Register && Reg.Kind == rk_CoprocReg);
335 StringRef getToken() const {
336 assert(Kind == k_Token && "Invalid access!");
337 return StringRef(Tok.Data, Tok.Length);
340 unsigned getReg() const override {
341 assert((Kind == k_Register) && "Invalid access!");
342 return Reg.RegNum;
345 const MCExpr *getImm() const {
346 assert((Kind == k_Immediate) && "Invalid access!");
347 return Imm.Val;
350 unsigned getMemBase() const {
351 assert((Kind == k_MemoryReg || Kind == k_MemoryImm) && "Invalid access!");
352 return Mem.Base;
355 unsigned getMemOffsetReg() const {
356 assert((Kind == k_MemoryReg) && "Invalid access!");
357 return Mem.OffsetReg;
360 const MCExpr *getMemOff() const {
361 assert((Kind == k_MemoryImm) && "Invalid access!");
362 return Mem.Off;
365 unsigned getASITag() const {
366 assert((Kind == k_ASITag) && "Invalid access!");
367 return ASI;
370 /// getStartLoc - Get the location of the first token of this operand.
371 SMLoc getStartLoc() const override {
372 return StartLoc;
374 /// getEndLoc - Get the location of the last token of this operand.
375 SMLoc getEndLoc() const override {
376 return EndLoc;
379 void print(raw_ostream &OS) const override {
380 switch (Kind) {
381 case k_Token: OS << "Token: " << getToken() << "\n"; break;
382 case k_Register: OS << "Reg: #" << getReg() << "\n"; break;
383 case k_Immediate: OS << "Imm: " << getImm() << "\n"; break;
384 case k_MemoryReg: OS << "Mem: " << getMemBase() << "+"
385 << getMemOffsetReg() << "\n"; break;
386 case k_MemoryImm: assert(getMemOff() != nullptr);
387 OS << "Mem: " << getMemBase()
388 << "+" << *getMemOff()
389 << "\n"; break;
390 case k_ASITag:
391 OS << "ASI tag: " << getASITag() << "\n";
392 break;
396 void addRegOperands(MCInst &Inst, unsigned N) const {
397 assert(N == 1 && "Invalid number of operands!");
398 Inst.addOperand(MCOperand::createReg(getReg()));
401 void addImmOperands(MCInst &Inst, unsigned N) const {
402 assert(N == 1 && "Invalid number of operands!");
403 const MCExpr *Expr = getImm();
404 addExpr(Inst, Expr);
407 void addShiftAmtImm5Operands(MCInst &Inst, unsigned N) const {
408 assert(N == 1 && "Invalid number of operands!");
409 addExpr(Inst, getImm());
411 void addShiftAmtImm6Operands(MCInst &Inst, unsigned N) const {
412 assert(N == 1 && "Invalid number of operands!");
413 addExpr(Inst, getImm());
416 void addExpr(MCInst &Inst, const MCExpr *Expr) const{
417 // Add as immediate when possible. Null MCExpr = 0.
418 if (!Expr)
419 Inst.addOperand(MCOperand::createImm(0));
420 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
421 Inst.addOperand(MCOperand::createImm(CE->getValue()));
422 else
423 Inst.addOperand(MCOperand::createExpr(Expr));
426 void addMEMrrOperands(MCInst &Inst, unsigned N) const {
427 assert(N == 2 && "Invalid number of operands!");
429 Inst.addOperand(MCOperand::createReg(getMemBase()));
431 assert(getMemOffsetReg() != 0 && "Invalid offset");
432 Inst.addOperand(MCOperand::createReg(getMemOffsetReg()));
435 void addMEMriOperands(MCInst &Inst, unsigned N) const {
436 assert(N == 2 && "Invalid number of operands!");
438 Inst.addOperand(MCOperand::createReg(getMemBase()));
440 const MCExpr *Expr = getMemOff();
441 addExpr(Inst, Expr);
444 void addASITagOperands(MCInst &Inst, unsigned N) const {
445 assert(N == 1 && "Invalid number of operands!");
446 Inst.addOperand(MCOperand::createImm(getASITag()));
449 void addMembarTagOperands(MCInst &Inst, unsigned N) const {
450 assert(N == 1 && "Invalid number of operands!");
451 const MCExpr *Expr = getImm();
452 addExpr(Inst, Expr);
455 void addCallTargetOperands(MCInst &Inst, unsigned N) const {
456 assert(N == 1 && "Invalid number of operands!");
457 addExpr(Inst, getImm());
460 void addTailRelocSymOperands(MCInst &Inst, unsigned N) const {
461 assert(N == 1 && "Invalid number of operands!");
462 addExpr(Inst, getImm());
465 static std::unique_ptr<SparcOperand> CreateToken(StringRef Str, SMLoc S) {
466 auto Op = std::make_unique<SparcOperand>(k_Token);
467 Op->Tok.Data = Str.data();
468 Op->Tok.Length = Str.size();
469 Op->StartLoc = S;
470 Op->EndLoc = S;
471 return Op;
474 static std::unique_ptr<SparcOperand> CreateReg(unsigned RegNum, unsigned Kind,
475 SMLoc S, SMLoc E) {
476 auto Op = std::make_unique<SparcOperand>(k_Register);
477 Op->Reg.RegNum = RegNum;
478 Op->Reg.Kind = (SparcOperand::RegisterKind)Kind;
479 Op->StartLoc = S;
480 Op->EndLoc = E;
481 return Op;
484 static std::unique_ptr<SparcOperand> CreateImm(const MCExpr *Val, SMLoc S,
485 SMLoc E) {
486 auto Op = std::make_unique<SparcOperand>(k_Immediate);
487 Op->Imm.Val = Val;
488 Op->StartLoc = S;
489 Op->EndLoc = E;
490 return Op;
493 static std::unique_ptr<SparcOperand> CreateASITag(unsigned Val, SMLoc S,
494 SMLoc E) {
495 auto Op = std::make_unique<SparcOperand>(k_ASITag);
496 Op->ASI = Val;
497 Op->StartLoc = S;
498 Op->EndLoc = E;
499 return Op;
502 static bool MorphToIntPairReg(SparcOperand &Op) {
503 unsigned Reg = Op.getReg();
504 assert(Op.Reg.Kind == rk_IntReg);
505 unsigned regIdx = 32;
506 if (Reg >= Sparc::G0 && Reg <= Sparc::G7)
507 regIdx = Reg - Sparc::G0;
508 else if (Reg >= Sparc::O0 && Reg <= Sparc::O7)
509 regIdx = Reg - Sparc::O0 + 8;
510 else if (Reg >= Sparc::L0 && Reg <= Sparc::L7)
511 regIdx = Reg - Sparc::L0 + 16;
512 else if (Reg >= Sparc::I0 && Reg <= Sparc::I7)
513 regIdx = Reg - Sparc::I0 + 24;
514 if (regIdx % 2 || regIdx > 31)
515 return false;
516 Op.Reg.RegNum = IntPairRegs[regIdx / 2];
517 Op.Reg.Kind = rk_IntPairReg;
518 return true;
521 static bool MorphToDoubleReg(SparcOperand &Op) {
522 unsigned Reg = Op.getReg();
523 assert(Op.Reg.Kind == rk_FloatReg);
524 unsigned regIdx = Reg - Sparc::F0;
525 if (regIdx % 2 || regIdx > 31)
526 return false;
527 Op.Reg.RegNum = DoubleRegs[regIdx / 2];
528 Op.Reg.Kind = rk_DoubleReg;
529 return true;
532 static bool MorphToQuadReg(SparcOperand &Op) {
533 unsigned Reg = Op.getReg();
534 unsigned regIdx = 0;
535 switch (Op.Reg.Kind) {
536 default: llvm_unreachable("Unexpected register kind!");
537 case rk_FloatReg:
538 regIdx = Reg - Sparc::F0;
539 if (regIdx % 4 || regIdx > 31)
540 return false;
541 Reg = QuadFPRegs[regIdx / 4];
542 break;
543 case rk_DoubleReg:
544 regIdx = Reg - Sparc::D0;
545 if (regIdx % 2 || regIdx > 31)
546 return false;
547 Reg = QuadFPRegs[regIdx / 2];
548 break;
550 Op.Reg.RegNum = Reg;
551 Op.Reg.Kind = rk_QuadReg;
552 return true;
555 static bool MorphToCoprocPairReg(SparcOperand &Op) {
556 unsigned Reg = Op.getReg();
557 assert(Op.Reg.Kind == rk_CoprocReg);
558 unsigned regIdx = 32;
559 if (Reg >= Sparc::C0 && Reg <= Sparc::C31)
560 regIdx = Reg - Sparc::C0;
561 if (regIdx % 2 || regIdx > 31)
562 return false;
563 Op.Reg.RegNum = CoprocPairRegs[regIdx / 2];
564 Op.Reg.Kind = rk_CoprocPairReg;
565 return true;
568 static std::unique_ptr<SparcOperand>
569 MorphToMEMrr(unsigned Base, std::unique_ptr<SparcOperand> Op) {
570 unsigned offsetReg = Op->getReg();
571 Op->Kind = k_MemoryReg;
572 Op->Mem.Base = Base;
573 Op->Mem.OffsetReg = offsetReg;
574 Op->Mem.Off = nullptr;
575 return Op;
578 static std::unique_ptr<SparcOperand>
579 CreateMEMr(unsigned Base, SMLoc S, SMLoc E) {
580 auto Op = std::make_unique<SparcOperand>(k_MemoryReg);
581 Op->Mem.Base = Base;
582 Op->Mem.OffsetReg = Sparc::G0; // always 0
583 Op->Mem.Off = nullptr;
584 Op->StartLoc = S;
585 Op->EndLoc = E;
586 return Op;
589 static std::unique_ptr<SparcOperand>
590 MorphToMEMri(unsigned Base, std::unique_ptr<SparcOperand> Op) {
591 const MCExpr *Imm = Op->getImm();
592 Op->Kind = k_MemoryImm;
593 Op->Mem.Base = Base;
594 Op->Mem.OffsetReg = 0;
595 Op->Mem.Off = Imm;
596 return Op;
600 } // end anonymous namespace
602 bool SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
603 SmallVectorImpl<MCInst> &Instructions) {
604 MCOperand MCRegOp = Inst.getOperand(0);
605 MCOperand MCValOp = Inst.getOperand(1);
606 assert(MCRegOp.isReg());
607 assert(MCValOp.isImm() || MCValOp.isExpr());
609 // the imm operand can be either an expression or an immediate.
610 bool IsImm = Inst.getOperand(1).isImm();
611 int64_t RawImmValue = IsImm ? MCValOp.getImm() : 0;
613 // Allow either a signed or unsigned 32-bit immediate.
614 if (RawImmValue < -2147483648LL || RawImmValue > 4294967295LL) {
615 return Error(IDLoc,
616 "set: argument must be between -2147483648 and 4294967295");
619 // If the value was expressed as a large unsigned number, that's ok.
620 // We want to see if it "looks like" a small signed number.
621 int32_t ImmValue = RawImmValue;
622 // For 'set' you can't use 'or' with a negative operand on V9 because
623 // that would splat the sign bit across the upper half of the destination
624 // register, whereas 'set' is defined to zero the high 32 bits.
625 bool IsEffectivelyImm13 =
626 IsImm && ((is64Bit() ? 0 : -4096) <= ImmValue && ImmValue < 4096);
627 const MCExpr *ValExpr;
628 if (IsImm)
629 ValExpr = MCConstantExpr::create(ImmValue, getContext());
630 else
631 ValExpr = MCValOp.getExpr();
633 MCOperand PrevReg = MCOperand::createReg(Sparc::G0);
635 // If not just a signed imm13 value, then either we use a 'sethi' with a
636 // following 'or', or a 'sethi' by itself if there are no more 1 bits.
637 // In either case, start with the 'sethi'.
638 if (!IsEffectivelyImm13) {
639 MCInst TmpInst;
640 const MCExpr *Expr = adjustPICRelocation(SparcMCExpr::VK_Sparc_HI, ValExpr);
641 TmpInst.setLoc(IDLoc);
642 TmpInst.setOpcode(SP::SETHIi);
643 TmpInst.addOperand(MCRegOp);
644 TmpInst.addOperand(MCOperand::createExpr(Expr));
645 Instructions.push_back(TmpInst);
646 PrevReg = MCRegOp;
649 // The low bits require touching in 3 cases:
650 // * A non-immediate value will always require both instructions.
651 // * An effectively imm13 value needs only an 'or' instruction.
652 // * Otherwise, an immediate that is not effectively imm13 requires the
653 // 'or' only if bits remain after clearing the 22 bits that 'sethi' set.
654 // If the low bits are known zeros, there's nothing to do.
655 // In the second case, and only in that case, must we NOT clear
656 // bits of the immediate value via the %lo() assembler function.
657 // Note also, the 'or' instruction doesn't mind a large value in the case
658 // where the operand to 'set' was 0xFFFFFzzz - it does exactly what you mean.
659 if (!IsImm || IsEffectivelyImm13 || (ImmValue & 0x3ff)) {
660 MCInst TmpInst;
661 const MCExpr *Expr;
662 if (IsEffectivelyImm13)
663 Expr = ValExpr;
664 else
665 Expr = adjustPICRelocation(SparcMCExpr::VK_Sparc_LO, ValExpr);
666 TmpInst.setLoc(IDLoc);
667 TmpInst.setOpcode(SP::ORri);
668 TmpInst.addOperand(MCRegOp);
669 TmpInst.addOperand(PrevReg);
670 TmpInst.addOperand(MCOperand::createExpr(Expr));
671 Instructions.push_back(TmpInst);
673 return false;
676 bool SparcAsmParser::expandSETX(MCInst &Inst, SMLoc IDLoc,
677 SmallVectorImpl<MCInst> &Instructions) {
678 MCOperand MCRegOp = Inst.getOperand(0);
679 MCOperand MCValOp = Inst.getOperand(1);
680 MCOperand MCTmpOp = Inst.getOperand(2);
681 assert(MCRegOp.isReg() && MCTmpOp.isReg());
682 assert(MCValOp.isImm() || MCValOp.isExpr());
684 // the imm operand can be either an expression or an immediate.
685 bool IsImm = MCValOp.isImm();
686 int64_t ImmValue = IsImm ? MCValOp.getImm() : 0;
688 const MCExpr *ValExpr = IsImm ? MCConstantExpr::create(ImmValue, getContext())
689 : MCValOp.getExpr();
691 // Very small immediates can be expressed directly as a single `or`.
692 if (IsImm && isInt<13>(ImmValue)) {
693 // or rd, val, rd
694 Instructions.push_back(MCInstBuilder(SP::ORri)
695 .addReg(MCRegOp.getReg())
696 .addReg(Sparc::G0)
697 .addExpr(ValExpr));
698 return false;
701 // Otherwise, first we set the lower half of the register.
703 // sethi %hi(val), rd
704 Instructions.push_back(
705 MCInstBuilder(SP::SETHIi)
706 .addReg(MCRegOp.getReg())
707 .addExpr(adjustPICRelocation(SparcMCExpr::VK_Sparc_HI, ValExpr)));
708 // or rd, %lo(val), rd
709 Instructions.push_back(
710 MCInstBuilder(SP::ORri)
711 .addReg(MCRegOp.getReg())
712 .addReg(MCRegOp.getReg())
713 .addExpr(adjustPICRelocation(SparcMCExpr::VK_Sparc_LO, ValExpr)));
715 // Small positive immediates can be expressed as a single `sethi`+`or`
716 // combination, so we can just return here.
717 if (IsImm && isUInt<32>(ImmValue))
718 return false;
720 // For bigger immediates, we need to generate the upper half, then shift and
721 // merge it with the lower half that has just been generated above.
723 // sethi %hh(val), tmp
724 Instructions.push_back(
725 MCInstBuilder(SP::SETHIi)
726 .addReg(MCTmpOp.getReg())
727 .addExpr(adjustPICRelocation(SparcMCExpr::VK_Sparc_HH, ValExpr)));
728 // or tmp, %hm(val), tmp
729 Instructions.push_back(
730 MCInstBuilder(SP::ORri)
731 .addReg(MCTmpOp.getReg())
732 .addReg(MCTmpOp.getReg())
733 .addExpr(adjustPICRelocation(SparcMCExpr::VK_Sparc_HM, ValExpr)));
734 // sllx tmp, 32, tmp
735 Instructions.push_back(MCInstBuilder(SP::SLLXri)
736 .addReg(MCTmpOp.getReg())
737 .addReg(MCTmpOp.getReg())
738 .addImm(32));
739 // or tmp, rd, rd
740 Instructions.push_back(MCInstBuilder(SP::ORrr)
741 .addReg(MCRegOp.getReg())
742 .addReg(MCTmpOp.getReg())
743 .addReg(MCRegOp.getReg()));
745 return false;
748 bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
749 OperandVector &Operands,
750 MCStreamer &Out,
751 uint64_t &ErrorInfo,
752 bool MatchingInlineAsm) {
753 MCInst Inst;
754 SmallVector<MCInst, 8> Instructions;
755 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
756 MatchingInlineAsm);
757 switch (MatchResult) {
758 case Match_Success: {
759 switch (Inst.getOpcode()) {
760 default:
761 Inst.setLoc(IDLoc);
762 Instructions.push_back(Inst);
763 break;
764 case SP::SET:
765 if (expandSET(Inst, IDLoc, Instructions))
766 return true;
767 break;
768 case SP::SETX:
769 if (expandSETX(Inst, IDLoc, Instructions))
770 return true;
771 break;
774 for (const MCInst &I : Instructions) {
775 Out.emitInstruction(I, getSTI());
777 return false;
780 case Match_MissingFeature:
781 return Error(IDLoc,
782 "instruction requires a CPU feature not currently enabled");
784 case Match_InvalidOperand: {
785 SMLoc ErrorLoc = IDLoc;
786 if (ErrorInfo != ~0ULL) {
787 if (ErrorInfo >= Operands.size())
788 return Error(IDLoc, "too few operands for instruction");
790 ErrorLoc = ((SparcOperand &)*Operands[ErrorInfo]).getStartLoc();
791 if (ErrorLoc == SMLoc())
792 ErrorLoc = IDLoc;
795 return Error(ErrorLoc, "invalid operand for instruction");
797 case Match_MnemonicFail:
798 return Error(IDLoc, "invalid instruction mnemonic");
800 llvm_unreachable("Implement any new match types added!");
803 bool SparcAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
804 SMLoc &EndLoc) {
805 if (!tryParseRegister(Reg, StartLoc, EndLoc).isSuccess())
806 return Error(StartLoc, "invalid register name");
807 return false;
810 ParseStatus SparcAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
811 SMLoc &EndLoc) {
812 const AsmToken &Tok = Parser.getTok();
813 StartLoc = Tok.getLoc();
814 EndLoc = Tok.getEndLoc();
815 Reg = Sparc::NoRegister;
816 if (getLexer().getKind() != AsmToken::Percent)
817 return ParseStatus::NoMatch;
818 Parser.Lex();
819 unsigned regKind = SparcOperand::rk_None;
820 if (matchRegisterName(Tok, Reg, regKind)) {
821 Parser.Lex();
822 return ParseStatus::Success;
825 getLexer().UnLex(Tok);
826 return ParseStatus::NoMatch;
829 static void applyMnemonicAliases(StringRef &Mnemonic,
830 const FeatureBitset &Features,
831 unsigned VariantID);
833 bool SparcAsmParser::ParseInstruction(ParseInstructionInfo &Info,
834 StringRef Name, SMLoc NameLoc,
835 OperandVector &Operands) {
837 // First operand in MCInst is instruction mnemonic.
838 Operands.push_back(SparcOperand::CreateToken(Name, NameLoc));
840 // apply mnemonic aliases, if any, so that we can parse operands correctly.
841 applyMnemonicAliases(Name, getAvailableFeatures(), 0);
843 if (getLexer().isNot(AsmToken::EndOfStatement)) {
844 // Read the first operand.
845 if (getLexer().is(AsmToken::Comma)) {
846 if (!parseBranchModifiers(Operands).isSuccess()) {
847 SMLoc Loc = getLexer().getLoc();
848 return Error(Loc, "unexpected token");
851 if (!parseOperand(Operands, Name).isSuccess()) {
852 SMLoc Loc = getLexer().getLoc();
853 return Error(Loc, "unexpected token");
856 while (getLexer().is(AsmToken::Comma) || getLexer().is(AsmToken::Plus)) {
857 if (getLexer().is(AsmToken::Plus)) {
858 // Plus tokens are significant in software_traps (p83, sparcv8.pdf). We must capture them.
859 Operands.push_back(SparcOperand::CreateToken("+", Parser.getTok().getLoc()));
861 Parser.Lex(); // Eat the comma or plus.
862 // Parse and remember the operand.
863 if (!parseOperand(Operands, Name).isSuccess()) {
864 SMLoc Loc = getLexer().getLoc();
865 return Error(Loc, "unexpected token");
869 if (getLexer().isNot(AsmToken::EndOfStatement)) {
870 SMLoc Loc = getLexer().getLoc();
871 return Error(Loc, "unexpected token");
873 Parser.Lex(); // Consume the EndOfStatement.
874 return false;
877 ParseStatus SparcAsmParser::parseDirective(AsmToken DirectiveID) {
878 StringRef IDVal = DirectiveID.getString();
880 if (IDVal == ".register") {
881 // For now, ignore .register directive.
882 Parser.eatToEndOfStatement();
883 return ParseStatus::Success;
885 if (IDVal == ".proc") {
886 // For compatibility, ignore this directive.
887 // (It's supposed to be an "optimization" in the Sun assembler)
888 Parser.eatToEndOfStatement();
889 return ParseStatus::Success;
892 // Let the MC layer to handle other directives.
893 return ParseStatus::NoMatch;
896 ParseStatus SparcAsmParser::parseMEMOperand(OperandVector &Operands) {
897 SMLoc S, E;
899 std::unique_ptr<SparcOperand> LHS;
900 if (!parseSparcAsmOperand(LHS).isSuccess())
901 return ParseStatus::NoMatch;
903 // Single immediate operand
904 if (LHS->isImm()) {
905 Operands.push_back(SparcOperand::MorphToMEMri(Sparc::G0, std::move(LHS)));
906 return ParseStatus::Success;
909 if (!LHS->isIntReg())
910 return Error(LHS->getStartLoc(), "invalid register kind for this operand");
912 AsmToken Tok = getLexer().getTok();
913 // The plus token may be followed by a register or an immediate value, the
914 // minus one is always interpreted as sign for the immediate value
915 if (Tok.is(AsmToken::Plus) || Tok.is(AsmToken::Minus)) {
916 (void)Parser.parseOptionalToken(AsmToken::Plus);
918 std::unique_ptr<SparcOperand> RHS;
919 if (!parseSparcAsmOperand(RHS).isSuccess())
920 return ParseStatus::NoMatch;
922 if (RHS->isReg() && !RHS->isIntReg())
923 return Error(RHS->getStartLoc(),
924 "invalid register kind for this operand");
926 Operands.push_back(
927 RHS->isImm()
928 ? SparcOperand::MorphToMEMri(LHS->getReg(), std::move(RHS))
929 : SparcOperand::MorphToMEMrr(LHS->getReg(), std::move(RHS)));
931 return ParseStatus::Success;
934 Operands.push_back(SparcOperand::CreateMEMr(LHS->getReg(), S, E));
935 return ParseStatus::Success;
938 template <unsigned N>
939 ParseStatus SparcAsmParser::parseShiftAmtImm(OperandVector &Operands) {
940 SMLoc S = Parser.getTok().getLoc();
941 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
943 // This is a register, not an immediate
944 if (getLexer().getKind() == AsmToken::Percent)
945 return ParseStatus::NoMatch;
947 const MCExpr *Expr;
948 if (getParser().parseExpression(Expr))
949 return ParseStatus::Failure;
951 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
952 if (!CE)
953 return Error(S, "constant expression expected");
955 if (!isUInt<N>(CE->getValue()))
956 return Error(S, "immediate shift value out of range");
958 Operands.push_back(SparcOperand::CreateImm(Expr, S, E));
959 return ParseStatus::Success;
962 template <SparcAsmParser::TailRelocKind Kind>
963 ParseStatus SparcAsmParser::parseTailRelocSym(OperandVector &Operands) {
964 SMLoc S = getLoc();
965 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
967 auto MatchesKind = [](SparcMCExpr::VariantKind VK) -> bool {
968 switch (Kind) {
969 case TailRelocKind::Load_GOT:
970 // Non-TLS relocations on ld (or ldx).
971 // ld [%rr + %rr], %rr, %rel(sym)
972 return VK == SparcMCExpr::VK_Sparc_GOTDATA_OP;
973 case TailRelocKind::Add_TLS:
974 // TLS relocations on add.
975 // add %rr, %rr, %rr, %rel(sym)
976 switch (VK) {
977 case SparcMCExpr::VK_Sparc_TLS_GD_ADD:
978 case SparcMCExpr::VK_Sparc_TLS_IE_ADD:
979 case SparcMCExpr::VK_Sparc_TLS_LDM_ADD:
980 case SparcMCExpr::VK_Sparc_TLS_LDO_ADD:
981 return true;
982 default:
983 return false;
985 case TailRelocKind::Load_TLS:
986 // TLS relocations on ld (or ldx).
987 // ld[x] %addr, %rr, %rel(sym)
988 switch (VK) {
989 case SparcMCExpr::VK_Sparc_TLS_IE_LD:
990 case SparcMCExpr::VK_Sparc_TLS_IE_LDX:
991 return true;
992 default:
993 return false;
995 case TailRelocKind::Call_TLS:
996 // TLS relocations on call.
997 // call sym, %rel(sym)
998 switch (VK) {
999 case SparcMCExpr::VK_Sparc_TLS_GD_CALL:
1000 case SparcMCExpr::VK_Sparc_TLS_LDM_CALL:
1001 return true;
1002 default:
1003 return false;
1006 llvm_unreachable("Unhandled SparcAsmParser::TailRelocKind enum");
1009 if (getLexer().getKind() != AsmToken::Percent)
1010 return Error(getLoc(), "expected '%' for operand modifier");
1012 const AsmToken Tok = Parser.getTok();
1013 getParser().Lex(); // Eat '%'
1015 if (getLexer().getKind() != AsmToken::Identifier)
1016 return Error(getLoc(), "expected valid identifier for operand modifier");
1018 StringRef Name = getParser().getTok().getIdentifier();
1019 SparcMCExpr::VariantKind VK = SparcMCExpr::parseVariantKind(Name);
1020 if (VK == SparcMCExpr::VK_Sparc_None)
1021 return Error(getLoc(), "invalid operand modifier");
1023 if (!MatchesKind(VK)) {
1024 // Did not match the specified set of relocation types, put '%' back.
1025 getLexer().UnLex(Tok);
1026 return ParseStatus::NoMatch;
1029 Parser.Lex(); // Eat the identifier.
1030 if (getLexer().getKind() != AsmToken::LParen)
1031 return Error(getLoc(), "expected '('");
1033 getParser().Lex(); // Eat '('
1034 const MCExpr *SubExpr;
1035 if (getParser().parseParenExpression(SubExpr, E))
1036 return ParseStatus::Failure;
1038 const MCExpr *Val = adjustPICRelocation(VK, SubExpr);
1039 Operands.push_back(SparcOperand::CreateImm(Val, S, E));
1040 return ParseStatus::Success;
1043 ParseStatus SparcAsmParser::parseMembarTag(OperandVector &Operands) {
1044 SMLoc S = Parser.getTok().getLoc();
1045 const MCExpr *EVal;
1046 int64_t ImmVal = 0;
1048 std::unique_ptr<SparcOperand> Mask;
1049 if (parseSparcAsmOperand(Mask).isSuccess()) {
1050 if (!Mask->isImm() || !Mask->getImm()->evaluateAsAbsolute(ImmVal) ||
1051 ImmVal < 0 || ImmVal > 127)
1052 return Error(S, "invalid membar mask number");
1055 while (getLexer().getKind() == AsmToken::Hash) {
1056 SMLoc TagStart = getLexer().getLoc();
1057 Parser.Lex(); // Eat the '#'.
1058 unsigned MaskVal = StringSwitch<unsigned>(Parser.getTok().getString())
1059 .Case("LoadLoad", 0x1)
1060 .Case("StoreLoad", 0x2)
1061 .Case("LoadStore", 0x4)
1062 .Case("StoreStore", 0x8)
1063 .Case("Lookaside", 0x10)
1064 .Case("MemIssue", 0x20)
1065 .Case("Sync", 0x40)
1066 .Default(0);
1068 Parser.Lex(); // Eat the identifier token.
1070 if (!MaskVal)
1071 return Error(TagStart, "unknown membar tag");
1073 ImmVal |= MaskVal;
1075 if (getLexer().getKind() == AsmToken::Pipe)
1076 Parser.Lex(); // Eat the '|'.
1079 EVal = MCConstantExpr::create(ImmVal, getContext());
1080 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1081 Operands.push_back(SparcOperand::CreateImm(EVal, S, E));
1082 return ParseStatus::Success;
1085 ParseStatus SparcAsmParser::parseASITag(OperandVector &Operands) {
1086 SMLoc S = Parser.getTok().getLoc();
1087 SMLoc E = Parser.getTok().getEndLoc();
1088 int64_t ASIVal = 0;
1090 if (is64Bit() && (getLexer().getKind() == AsmToken::Hash)) {
1091 // For now we only support named tags for 64-bit/V9 systems.
1092 // TODO: add support for 32-bit/V8 systems.
1093 SMLoc TagStart = getLexer().peekTok(false).getLoc();
1094 Parser.Lex(); // Eat the '#'.
1095 auto ASIName = Parser.getTok().getString();
1096 auto ASITag = SparcASITag::lookupASITagByName(ASIName);
1097 if (!ASITag)
1098 ASITag = SparcASITag::lookupASITagByAltName(ASIName);
1099 Parser.Lex(); // Eat the identifier token.
1101 if (!ASITag)
1102 return Error(TagStart, "unknown ASI tag");
1104 ASIVal = ASITag->Encoding;
1105 } else if (!getParser().parseAbsoluteExpression(ASIVal)) {
1106 if (!isUInt<8>(ASIVal))
1107 return Error(S, "invalid ASI number, must be between 0 and 255");
1108 } else {
1109 return Error(
1110 S, is64Bit()
1111 ? "malformed ASI tag, must be %asi, a constant integer "
1112 "expression, or a named tag"
1113 : "malformed ASI tag, must be a constant integer expression");
1116 Operands.push_back(SparcOperand::CreateASITag(ASIVal, S, E));
1117 return ParseStatus::Success;
1120 ParseStatus SparcAsmParser::parseCallTarget(OperandVector &Operands) {
1121 SMLoc S = Parser.getTok().getLoc();
1122 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1124 switch (getLexer().getKind()) {
1125 default:
1126 return ParseStatus::NoMatch;
1127 case AsmToken::LParen:
1128 case AsmToken::Integer:
1129 case AsmToken::Identifier:
1130 case AsmToken::Dot:
1131 break;
1134 const MCExpr *DestValue;
1135 if (getParser().parseExpression(DestValue))
1136 return ParseStatus::NoMatch;
1138 bool IsPic = getContext().getObjectFileInfo()->isPositionIndependent();
1139 SparcMCExpr::VariantKind Kind =
1140 IsPic ? SparcMCExpr::VK_Sparc_WPLT30 : SparcMCExpr::VK_Sparc_WDISP30;
1142 const MCExpr *DestExpr = SparcMCExpr::create(Kind, DestValue, getContext());
1143 Operands.push_back(SparcOperand::CreateImm(DestExpr, S, E));
1144 return ParseStatus::Success;
1147 ParseStatus SparcAsmParser::parseOperand(OperandVector &Operands,
1148 StringRef Mnemonic) {
1150 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic);
1152 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1153 // there was a match, but an error occurred, in which case, just return that
1154 // the operand parsing failed.
1155 if (Res.isSuccess() || Res.isFailure())
1156 return Res;
1158 if (getLexer().is(AsmToken::LBrac)) {
1159 // Memory operand
1160 Operands.push_back(SparcOperand::CreateToken("[",
1161 Parser.getTok().getLoc()));
1162 Parser.Lex(); // Eat the [
1164 if (Mnemonic == "cas" || Mnemonic == "casl" || Mnemonic == "casa" ||
1165 Mnemonic == "casx" || Mnemonic == "casxl" || Mnemonic == "casxa") {
1166 SMLoc S = Parser.getTok().getLoc();
1167 if (getLexer().getKind() != AsmToken::Percent)
1168 return ParseStatus::NoMatch;
1169 Parser.Lex(); // eat %
1171 MCRegister RegNo;
1172 unsigned RegKind;
1173 if (!matchRegisterName(Parser.getTok(), RegNo, RegKind))
1174 return ParseStatus::NoMatch;
1176 Parser.Lex(); // Eat the identifier token.
1177 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer()-1);
1178 Operands.push_back(SparcOperand::CreateReg(RegNo, RegKind, S, E));
1179 Res = ParseStatus::Success;
1180 } else {
1181 Res = parseMEMOperand(Operands);
1184 if (!Res.isSuccess())
1185 return Res;
1187 if (!getLexer().is(AsmToken::RBrac))
1188 return ParseStatus::Failure;
1190 Operands.push_back(SparcOperand::CreateToken("]",
1191 Parser.getTok().getLoc()));
1192 Parser.Lex(); // Eat the ]
1194 // Parse an optional address-space identifier after the address.
1195 // This will be either an immediate constant expression, or, on 64-bit
1196 // processors, the %asi register.
1197 if (is64Bit() && getLexer().is(AsmToken::Percent)) {
1198 SMLoc S = Parser.getTok().getLoc();
1199 Parser.Lex(); // Eat the %.
1200 const AsmToken Tok = Parser.getTok();
1201 if (Tok.is(AsmToken::Identifier) && Tok.getString() == "asi") {
1202 // Here we patch the MEM operand from [base + %g0] into [base + 0]
1203 // as memory operations with ASI tag stored in %asi register needs
1204 // to use immediate offset. We need to do this because Reg addressing
1205 // will be parsed as Reg+G0 initially.
1206 // This allows forms such as `ldxa [%o0] %asi, %o0` to parse correctly.
1207 SparcOperand &OldMemOp = (SparcOperand &)*Operands[Operands.size() - 2];
1208 if (OldMemOp.isMEMrr()) {
1209 if (OldMemOp.getMemOffsetReg() != Sparc::G0) {
1210 return Error(S, "invalid operand for instruction");
1212 Operands[Operands.size() - 2] = SparcOperand::MorphToMEMri(
1213 OldMemOp.getMemBase(),
1214 SparcOperand::CreateImm(MCConstantExpr::create(0, getContext()),
1215 OldMemOp.getStartLoc(),
1216 OldMemOp.getEndLoc()));
1218 Parser.Lex(); // Eat the identifier.
1219 // In this context, we convert the register operand into
1220 // a plain "%asi" token since the register access is already
1221 // implicit in the instruction definition and encoding.
1222 // See LoadASI/StoreASI in SparcInstrInfo.td.
1223 Operands.push_back(SparcOperand::CreateToken("%asi", S));
1224 return ParseStatus::Success;
1227 return Error(S, "malformed ASI tag, must be %asi, a constant integer "
1228 "expression, or a named tag");
1231 // If we're not at the end of statement and the next token is not a comma,
1232 // then it is an immediate ASI value.
1233 if (getLexer().isNot(AsmToken::EndOfStatement) &&
1234 getLexer().isNot(AsmToken::Comma))
1235 return parseASITag(Operands);
1236 return ParseStatus::Success;
1239 std::unique_ptr<SparcOperand> Op;
1241 Res = parseSparcAsmOperand(Op, (Mnemonic == "call"));
1242 if (!Res.isSuccess() || !Op)
1243 return ParseStatus::Failure;
1245 // Push the parsed operand into the list of operands
1246 Operands.push_back(std::move(Op));
1248 return ParseStatus::Success;
1251 ParseStatus
1252 SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op,
1253 bool isCall) {
1254 SMLoc S = Parser.getTok().getLoc();
1255 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1256 const MCExpr *EVal;
1258 Op = nullptr;
1259 switch (getLexer().getKind()) {
1260 default: break;
1262 case AsmToken::Percent: {
1263 Parser.Lex(); // Eat the '%'.
1264 MCRegister Reg;
1265 unsigned RegKind;
1266 if (matchRegisterName(Parser.getTok(), Reg, RegKind)) {
1267 StringRef Name = Parser.getTok().getString();
1268 Parser.Lex(); // Eat the identifier token.
1269 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1270 if (Reg == Sparc::ICC && Name == "xcc")
1271 Op = SparcOperand::CreateToken("%xcc", S);
1272 else
1273 Op = SparcOperand::CreateReg(Reg, RegKind, S, E);
1274 break;
1276 if (matchSparcAsmModifiers(EVal, E)) {
1277 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1278 Op = SparcOperand::CreateImm(EVal, S, E);
1280 break;
1283 case AsmToken::Plus:
1284 case AsmToken::Minus:
1285 case AsmToken::Integer:
1286 case AsmToken::LParen:
1287 case AsmToken::Dot:
1288 case AsmToken::Identifier:
1289 if (getParser().parseExpression(EVal, E))
1290 break;
1292 int64_t Res;
1293 if (!EVal->evaluateAsAbsolute(Res)) {
1294 SparcMCExpr::VariantKind Kind = SparcMCExpr::VK_Sparc_13;
1296 if (getContext().getObjectFileInfo()->isPositionIndependent()) {
1297 if (isCall)
1298 Kind = SparcMCExpr::VK_Sparc_WPLT30;
1299 else
1300 Kind = SparcMCExpr::VK_Sparc_GOT13;
1302 EVal = SparcMCExpr::create(Kind, EVal, getContext());
1304 Op = SparcOperand::CreateImm(EVal, S, E);
1305 break;
1307 return Op ? ParseStatus::Success : ParseStatus::Failure;
1310 ParseStatus SparcAsmParser::parseBranchModifiers(OperandVector &Operands) {
1311 // parse (,a|,pn|,pt)+
1313 while (getLexer().is(AsmToken::Comma)) {
1314 Parser.Lex(); // Eat the comma
1316 if (!getLexer().is(AsmToken::Identifier))
1317 return ParseStatus::Failure;
1318 StringRef modName = Parser.getTok().getString();
1319 if (modName == "a" || modName == "pn" || modName == "pt") {
1320 Operands.push_back(SparcOperand::CreateToken(modName,
1321 Parser.getTok().getLoc()));
1322 Parser.Lex(); // eat the identifier.
1325 return ParseStatus::Success;
1328 bool SparcAsmParser::matchRegisterName(const AsmToken &Tok, MCRegister &RegNo,
1329 unsigned &RegKind) {
1330 int64_t intVal = 0;
1331 RegNo = 0;
1332 RegKind = SparcOperand::rk_None;
1333 if (Tok.is(AsmToken::Identifier)) {
1334 StringRef name = Tok.getString();
1336 // %fp
1337 if (name.equals("fp")) {
1338 RegNo = Sparc::I6;
1339 RegKind = SparcOperand::rk_IntReg;
1340 return true;
1342 // %sp
1343 if (name.equals("sp")) {
1344 RegNo = Sparc::O6;
1345 RegKind = SparcOperand::rk_IntReg;
1346 return true;
1349 if (name.equals("y")) {
1350 RegNo = Sparc::Y;
1351 RegKind = SparcOperand::rk_Special;
1352 return true;
1355 if (name.substr(0, 3).equals_insensitive("asr") &&
1356 !name.substr(3).getAsInteger(10, intVal) && intVal > 0 && intVal < 32) {
1357 RegNo = ASRRegs[intVal];
1358 RegKind = SparcOperand::rk_Special;
1359 return true;
1362 if (name.equals("fprs")) {
1363 RegNo = Sparc::ASR6;
1364 RegKind = SparcOperand::rk_Special;
1365 return true;
1368 if (name.equals("icc")) {
1369 RegNo = Sparc::ICC;
1370 RegKind = SparcOperand::rk_Special;
1371 return true;
1374 if (name.equals("psr")) {
1375 RegNo = Sparc::PSR;
1376 RegKind = SparcOperand::rk_Special;
1377 return true;
1380 if (name.equals("fsr")) {
1381 RegNo = Sparc::FSR;
1382 RegKind = SparcOperand::rk_Special;
1383 return true;
1386 if (name.equals("fq")) {
1387 RegNo = Sparc::FQ;
1388 RegKind = SparcOperand::rk_Special;
1389 return true;
1392 if (name.equals("csr")) {
1393 RegNo = Sparc::CPSR;
1394 RegKind = SparcOperand::rk_Special;
1395 return true;
1398 if (name.equals("cq")) {
1399 RegNo = Sparc::CPQ;
1400 RegKind = SparcOperand::rk_Special;
1401 return true;
1404 if (name.equals("wim")) {
1405 RegNo = Sparc::WIM;
1406 RegKind = SparcOperand::rk_Special;
1407 return true;
1410 if (name.equals("tbr")) {
1411 RegNo = Sparc::TBR;
1412 RegKind = SparcOperand::rk_Special;
1413 return true;
1416 if (name.equals("xcc")) {
1417 // FIXME:: check 64bit.
1418 RegNo = Sparc::ICC;
1419 RegKind = SparcOperand::rk_Special;
1420 return true;
1423 // %fcc0 - %fcc3
1424 if (name.substr(0, 3).equals_insensitive("fcc") &&
1425 !name.substr(3).getAsInteger(10, intVal) && intVal < 4) {
1426 // FIXME: check 64bit and handle %fcc1 - %fcc3
1427 RegNo = Sparc::FCC0 + intVal;
1428 RegKind = SparcOperand::rk_Special;
1429 return true;
1432 // %g0 - %g7
1433 if (name.substr(0, 1).equals_insensitive("g") &&
1434 !name.substr(1).getAsInteger(10, intVal) && intVal < 8) {
1435 RegNo = IntRegs[intVal];
1436 RegKind = SparcOperand::rk_IntReg;
1437 return true;
1439 // %o0 - %o7
1440 if (name.substr(0, 1).equals_insensitive("o") &&
1441 !name.substr(1).getAsInteger(10, intVal) && intVal < 8) {
1442 RegNo = IntRegs[8 + intVal];
1443 RegKind = SparcOperand::rk_IntReg;
1444 return true;
1446 if (name.substr(0, 1).equals_insensitive("l") &&
1447 !name.substr(1).getAsInteger(10, intVal) && intVal < 8) {
1448 RegNo = IntRegs[16 + intVal];
1449 RegKind = SparcOperand::rk_IntReg;
1450 return true;
1452 if (name.substr(0, 1).equals_insensitive("i") &&
1453 !name.substr(1).getAsInteger(10, intVal) && intVal < 8) {
1454 RegNo = IntRegs[24 + intVal];
1455 RegKind = SparcOperand::rk_IntReg;
1456 return true;
1458 // %f0 - %f31
1459 if (name.substr(0, 1).equals_insensitive("f") &&
1460 !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 32) {
1461 RegNo = FloatRegs[intVal];
1462 RegKind = SparcOperand::rk_FloatReg;
1463 return true;
1465 // %f32 - %f62
1466 if (name.substr(0, 1).equals_insensitive("f") &&
1467 !name.substr(1, 2).getAsInteger(10, intVal) && intVal >= 32 &&
1468 intVal <= 62 && (intVal % 2 == 0)) {
1469 // FIXME: Check V9
1470 RegNo = DoubleRegs[intVal/2];
1471 RegKind = SparcOperand::rk_DoubleReg;
1472 return true;
1475 // %r0 - %r31
1476 if (name.substr(0, 1).equals_insensitive("r") &&
1477 !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) {
1478 RegNo = IntRegs[intVal];
1479 RegKind = SparcOperand::rk_IntReg;
1480 return true;
1483 // %c0 - %c31
1484 if (name.substr(0, 1).equals_insensitive("c") &&
1485 !name.substr(1).getAsInteger(10, intVal) && intVal < 32) {
1486 RegNo = CoprocRegs[intVal];
1487 RegKind = SparcOperand::rk_CoprocReg;
1488 return true;
1491 if (name.equals("tpc")) {
1492 RegNo = Sparc::TPC;
1493 RegKind = SparcOperand::rk_Special;
1494 return true;
1496 if (name.equals("tnpc")) {
1497 RegNo = Sparc::TNPC;
1498 RegKind = SparcOperand::rk_Special;
1499 return true;
1501 if (name.equals("tstate")) {
1502 RegNo = Sparc::TSTATE;
1503 RegKind = SparcOperand::rk_Special;
1504 return true;
1506 if (name.equals("tt")) {
1507 RegNo = Sparc::TT;
1508 RegKind = SparcOperand::rk_Special;
1509 return true;
1511 if (name.equals("tick")) {
1512 RegNo = Sparc::TICK;
1513 RegKind = SparcOperand::rk_Special;
1514 return true;
1516 if (name.equals("tba")) {
1517 RegNo = Sparc::TBA;
1518 RegKind = SparcOperand::rk_Special;
1519 return true;
1521 if (name.equals("pstate")) {
1522 RegNo = Sparc::PSTATE;
1523 RegKind = SparcOperand::rk_Special;
1524 return true;
1526 if (name.equals("tl")) {
1527 RegNo = Sparc::TL;
1528 RegKind = SparcOperand::rk_Special;
1529 return true;
1531 if (name.equals("pil")) {
1532 RegNo = Sparc::PIL;
1533 RegKind = SparcOperand::rk_Special;
1534 return true;
1536 if (name.equals("cwp")) {
1537 RegNo = Sparc::CWP;
1538 RegKind = SparcOperand::rk_Special;
1539 return true;
1541 if (name.equals("cansave")) {
1542 RegNo = Sparc::CANSAVE;
1543 RegKind = SparcOperand::rk_Special;
1544 return true;
1546 if (name.equals("canrestore")) {
1547 RegNo = Sparc::CANRESTORE;
1548 RegKind = SparcOperand::rk_Special;
1549 return true;
1551 if (name.equals("cleanwin")) {
1552 RegNo = Sparc::CLEANWIN;
1553 RegKind = SparcOperand::rk_Special;
1554 return true;
1556 if (name.equals("otherwin")) {
1557 RegNo = Sparc::OTHERWIN;
1558 RegKind = SparcOperand::rk_Special;
1559 return true;
1561 if (name.equals("wstate")) {
1562 RegNo = Sparc::WSTATE;
1563 RegKind = SparcOperand::rk_Special;
1564 return true;
1566 if (name.equals("pc")) {
1567 RegNo = Sparc::ASR5;
1568 RegKind = SparcOperand::rk_Special;
1569 return true;
1571 if (name.equals("asi")) {
1572 RegNo = Sparc::ASR3;
1573 RegKind = SparcOperand::rk_Special;
1574 return true;
1576 if (name.equals("ccr")) {
1577 RegNo = Sparc::ASR2;
1578 RegKind = SparcOperand::rk_Special;
1579 return true;
1581 if (name.equals("gl")) {
1582 RegNo = Sparc::GL;
1583 RegKind = SparcOperand::rk_Special;
1584 return true;
1586 if (name.equals("ver")) {
1587 RegNo = Sparc::VER;
1588 RegKind = SparcOperand::rk_Special;
1589 return true;
1592 // JPS1 extension - aliases for ASRs
1593 // Section A.51 - Read State Register
1594 if (name.equals("pcr")) {
1595 RegNo = Sparc::ASR16;
1596 RegKind = SparcOperand::rk_Special;
1597 return true;
1599 if (name.equals("pic")) {
1600 RegNo = Sparc::ASR17;
1601 RegKind = SparcOperand::rk_Special;
1602 return true;
1604 if (name.equals("dcr")) {
1605 RegNo = Sparc::ASR18;
1606 RegKind = SparcOperand::rk_Special;
1607 return true;
1609 if (name.equals("gsr")) {
1610 RegNo = Sparc::ASR19;
1611 RegKind = SparcOperand::rk_Special;
1612 return true;
1614 if (name.equals("softint")) {
1615 RegNo = Sparc::ASR22;
1616 RegKind = SparcOperand::rk_Special;
1617 return true;
1619 if (name.equals("tick_cmpr")) {
1620 RegNo = Sparc::ASR23;
1621 RegKind = SparcOperand::rk_Special;
1622 return true;
1624 if (name.equals("stick") || name.equals("sys_tick")) {
1625 RegNo = Sparc::ASR24;
1626 RegKind = SparcOperand::rk_Special;
1627 return true;
1629 if (name.equals("stick_cmpr") || name.equals("sys_tick_cmpr")) {
1630 RegNo = Sparc::ASR25;
1631 RegKind = SparcOperand::rk_Special;
1632 return true;
1635 return false;
1638 // Determine if an expression contains a reference to the symbol
1639 // "_GLOBAL_OFFSET_TABLE_".
1640 static bool hasGOTReference(const MCExpr *Expr) {
1641 switch (Expr->getKind()) {
1642 case MCExpr::Target:
1643 if (const SparcMCExpr *SE = dyn_cast<SparcMCExpr>(Expr))
1644 return hasGOTReference(SE->getSubExpr());
1645 break;
1647 case MCExpr::Constant:
1648 break;
1650 case MCExpr::Binary: {
1651 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
1652 return hasGOTReference(BE->getLHS()) || hasGOTReference(BE->getRHS());
1655 case MCExpr::SymbolRef: {
1656 const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
1657 return (SymRef.getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_");
1660 case MCExpr::Unary:
1661 return hasGOTReference(cast<MCUnaryExpr>(Expr)->getSubExpr());
1663 return false;
1666 const SparcMCExpr *
1667 SparcAsmParser::adjustPICRelocation(SparcMCExpr::VariantKind VK,
1668 const MCExpr *subExpr) {
1669 // When in PIC mode, "%lo(...)" and "%hi(...)" behave differently.
1670 // If the expression refers contains _GLOBAL_OFFSET_TABLE, it is
1671 // actually a %pc10 or %pc22 relocation. Otherwise, they are interpreted
1672 // as %got10 or %got22 relocation.
1674 if (getContext().getObjectFileInfo()->isPositionIndependent()) {
1675 switch(VK) {
1676 default: break;
1677 case SparcMCExpr::VK_Sparc_LO:
1678 VK = (hasGOTReference(subExpr) ? SparcMCExpr::VK_Sparc_PC10
1679 : SparcMCExpr::VK_Sparc_GOT10);
1680 break;
1681 case SparcMCExpr::VK_Sparc_HI:
1682 VK = (hasGOTReference(subExpr) ? SparcMCExpr::VK_Sparc_PC22
1683 : SparcMCExpr::VK_Sparc_GOT22);
1684 break;
1688 return SparcMCExpr::create(VK, subExpr, getContext());
1691 bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
1692 SMLoc &EndLoc) {
1693 AsmToken Tok = Parser.getTok();
1694 if (!Tok.is(AsmToken::Identifier))
1695 return false;
1697 StringRef name = Tok.getString();
1699 SparcMCExpr::VariantKind VK = SparcMCExpr::parseVariantKind(name);
1700 switch (VK) {
1701 case SparcMCExpr::VK_Sparc_None:
1702 Error(getLoc(), "invalid operand modifier");
1703 return false;
1705 case SparcMCExpr::VK_Sparc_GOTDATA_OP:
1706 case SparcMCExpr::VK_Sparc_TLS_GD_ADD:
1707 case SparcMCExpr::VK_Sparc_TLS_GD_CALL:
1708 case SparcMCExpr::VK_Sparc_TLS_IE_ADD:
1709 case SparcMCExpr::VK_Sparc_TLS_IE_LD:
1710 case SparcMCExpr::VK_Sparc_TLS_IE_LDX:
1711 case SparcMCExpr::VK_Sparc_TLS_LDM_ADD:
1712 case SparcMCExpr::VK_Sparc_TLS_LDM_CALL:
1713 case SparcMCExpr::VK_Sparc_TLS_LDO_ADD:
1714 // These are special-cased at tablegen level.
1715 return false;
1717 default:
1718 break;
1721 Parser.Lex(); // Eat the identifier.
1722 if (Parser.getTok().getKind() != AsmToken::LParen)
1723 return false;
1725 Parser.Lex(); // Eat the LParen token.
1726 const MCExpr *subExpr;
1727 if (Parser.parseParenExpression(subExpr, EndLoc))
1728 return false;
1730 EVal = adjustPICRelocation(VK, subExpr);
1731 return true;
1734 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSparcAsmParser() {
1735 RegisterMCAsmParser<SparcAsmParser> A(getTheSparcTarget());
1736 RegisterMCAsmParser<SparcAsmParser> B(getTheSparcV9Target());
1737 RegisterMCAsmParser<SparcAsmParser> C(getTheSparcelTarget());
1740 #define GET_REGISTER_MATCHER
1741 #define GET_MATCHER_IMPLEMENTATION
1742 #include "SparcGenAsmMatcher.inc"
1744 unsigned SparcAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,
1745 unsigned Kind) {
1746 SparcOperand &Op = (SparcOperand &)GOp;
1747 if (Op.isFloatOrDoubleReg()) {
1748 switch (Kind) {
1749 default: break;
1750 case MCK_DFPRegs:
1751 if (!Op.isFloatReg() || SparcOperand::MorphToDoubleReg(Op))
1752 return MCTargetAsmParser::Match_Success;
1753 break;
1754 case MCK_QFPRegs:
1755 if (SparcOperand::MorphToQuadReg(Op))
1756 return MCTargetAsmParser::Match_Success;
1757 break;
1760 if (Op.isIntReg() && Kind == MCK_IntPair) {
1761 if (SparcOperand::MorphToIntPairReg(Op))
1762 return MCTargetAsmParser::Match_Success;
1764 if (Op.isCoprocReg() && Kind == MCK_CoprocPair) {
1765 if (SparcOperand::MorphToCoprocPairReg(Op))
1766 return MCTargetAsmParser::Match_Success;
1768 return Match_InvalidOperand;