1 //===-- SparcAsmParser.cpp - Parse Sparc assembly to MCInst instructions --===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/SparcMCTargetDesc.h"
11 #include "MCTargetDesc/SparcMCExpr.h"
12 #include "llvm/ADT/STLExtras.h"
13 #include "llvm/MC/MCContext.h"
14 #include "llvm/MC/MCInst.h"
15 #include "llvm/MC/MCObjectFileInfo.h"
16 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
17 #include "llvm/MC/MCStreamer.h"
18 #include "llvm/MC/MCSubtargetInfo.h"
19 #include "llvm/MC/MCSymbol.h"
20 #include "llvm/MC/MCTargetAsmParser.h"
21 #include "llvm/Support/TargetRegistry.h"
25 // The generated AsmMatcher SparcGenAsmMatcher uses "Sparc" as the target
26 // namespace. But SPARC backend uses "SP" as its namespace.
35 class SparcAsmParser : public MCTargetAsmParser {
40 /// @name Auto-generated Match Functions
43 #define GET_ASSEMBLER_HEADER
44 #include "SparcGenAsmMatcher.inc"
48 // public interface of the MCTargetAsmParser.
49 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
50 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
51 MCStreamer &Out, unsigned &ErrorInfo,
52 bool MatchingInlineAsm);
53 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
54 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
56 SmallVectorImpl<MCParsedAsmOperand*> &Operands);
57 bool ParseDirective(AsmToken DirectiveID);
59 virtual unsigned validateTargetOperandClass(MCParsedAsmOperand *Op,
62 // Custom parse functions for Sparc specific operands.
64 parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
67 parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
71 parseSparcAsmOperand(SparcOperand *&Operand, bool isCall = false);
73 // returns true if Tok is matched to a register and returns register in RegNo.
74 bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo,
77 bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc);
78 bool parseDirectiveWord(unsigned Size, SMLoc L);
80 bool is64Bit() const { return STI.getTargetTriple().startswith("sparcv9"); }
82 SparcAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
83 const MCInstrInfo &MII)
84 : MCTargetAsmParser(), STI(sti), Parser(parser) {
85 // Initialize the set of available features.
86 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
91 static unsigned IntRegs[32] = {
92 Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,
93 Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,
94 Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,
95 Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,
96 Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,
97 Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,
98 Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,
99 Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };
101 static unsigned FloatRegs[32] = {
102 Sparc::F0, Sparc::F1, Sparc::F2, Sparc::F3,
103 Sparc::F4, Sparc::F5, Sparc::F6, Sparc::F7,
104 Sparc::F8, Sparc::F9, Sparc::F10, Sparc::F11,
105 Sparc::F12, Sparc::F13, Sparc::F14, Sparc::F15,
106 Sparc::F16, Sparc::F17, Sparc::F18, Sparc::F19,
107 Sparc::F20, Sparc::F21, Sparc::F22, Sparc::F23,
108 Sparc::F24, Sparc::F25, Sparc::F26, Sparc::F27,
109 Sparc::F28, Sparc::F29, Sparc::F30, Sparc::F31 };
111 static unsigned DoubleRegs[32] = {
112 Sparc::D0, Sparc::D1, Sparc::D2, Sparc::D3,
113 Sparc::D4, Sparc::D5, Sparc::D6, Sparc::D7,
114 Sparc::D8, Sparc::D7, Sparc::D8, Sparc::D9,
115 Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,
116 Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,
117 Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,
118 Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,
119 Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };
121 static unsigned QuadFPRegs[32] = {
122 Sparc::Q0, Sparc::Q1, Sparc::Q2, Sparc::Q3,
123 Sparc::Q4, Sparc::Q5, Sparc::Q6, Sparc::Q7,
124 Sparc::Q8, Sparc::Q9, Sparc::Q10, Sparc::Q11,
125 Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
128 /// SparcOperand - Instances of this class represent a parsed Sparc machine
130 class SparcOperand : public MCParsedAsmOperand {
150 SMLoc StartLoc, EndLoc;
152 SparcOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
181 bool isToken() const { return Kind == k_Token; }
182 bool isReg() const { return Kind == k_Register; }
183 bool isImm() const { return Kind == k_Immediate; }
184 bool isMem() const { return isMEMrr() || isMEMri(); }
185 bool isMEMrr() const { return Kind == k_MemoryReg; }
186 bool isMEMri() const { return Kind == k_MemoryImm; }
188 bool isFloatReg() const {
189 return (Kind == k_Register && Reg.Kind == rk_FloatReg);
192 bool isFloatOrDoubleReg() const {
193 return (Kind == k_Register && (Reg.Kind == rk_FloatReg
194 || Reg.Kind == rk_DoubleReg));
198 StringRef getToken() const {
199 assert(Kind == k_Token && "Invalid access!");
200 return StringRef(Tok.Data, Tok.Length);
203 unsigned getReg() const {
204 assert((Kind == k_Register) && "Invalid access!");
208 const MCExpr *getImm() const {
209 assert((Kind == k_Immediate) && "Invalid access!");
213 unsigned getMemBase() const {
214 assert((Kind == k_MemoryReg || Kind == k_MemoryImm) && "Invalid access!");
218 unsigned getMemOffsetReg() const {
219 assert((Kind == k_MemoryReg) && "Invalid access!");
220 return Mem.OffsetReg;
223 const MCExpr *getMemOff() const {
224 assert((Kind == k_MemoryImm) && "Invalid access!");
228 /// getStartLoc - Get the location of the first token of this operand.
229 SMLoc getStartLoc() const {
232 /// getEndLoc - Get the location of the last token of this operand.
233 SMLoc getEndLoc() const {
237 virtual void print(raw_ostream &OS) const {
239 case k_Token: OS << "Token: " << getToken() << "\n"; break;
240 case k_Register: OS << "Reg: #" << getReg() << "\n"; break;
241 case k_Immediate: OS << "Imm: " << getImm() << "\n"; break;
242 case k_MemoryReg: OS << "Mem: " << getMemBase() << "+"
243 << getMemOffsetReg() << "\n"; break;
244 case k_MemoryImm: assert(getMemOff() != 0);
245 OS << "Mem: " << getMemBase()
246 << "+" << *getMemOff()
251 void addRegOperands(MCInst &Inst, unsigned N) const {
252 assert(N == 1 && "Invalid number of operands!");
253 Inst.addOperand(MCOperand::CreateReg(getReg()));
256 void addImmOperands(MCInst &Inst, unsigned N) const {
257 assert(N == 1 && "Invalid number of operands!");
258 const MCExpr *Expr = getImm();
262 void addExpr(MCInst &Inst, const MCExpr *Expr) const{
263 // Add as immediate when possible. Null MCExpr = 0.
265 Inst.addOperand(MCOperand::CreateImm(0));
266 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
267 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
269 Inst.addOperand(MCOperand::CreateExpr(Expr));
272 void addMEMrrOperands(MCInst &Inst, unsigned N) const {
273 assert(N == 2 && "Invalid number of operands!");
275 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
277 assert(getMemOffsetReg() != 0 && "Invalid offset");
278 Inst.addOperand(MCOperand::CreateReg(getMemOffsetReg()));
281 void addMEMriOperands(MCInst &Inst, unsigned N) const {
282 assert(N == 2 && "Invalid number of operands!");
284 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
286 const MCExpr *Expr = getMemOff();
290 static SparcOperand *CreateToken(StringRef Str, SMLoc S) {
291 SparcOperand *Op = new SparcOperand(k_Token);
292 Op->Tok.Data = Str.data();
293 Op->Tok.Length = Str.size();
299 static SparcOperand *CreateReg(unsigned RegNum,
302 SparcOperand *Op = new SparcOperand(k_Register);
303 Op->Reg.RegNum = RegNum;
304 Op->Reg.Kind = (SparcOperand::RegisterKind)Kind;
310 static SparcOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
311 SparcOperand *Op = new SparcOperand(k_Immediate);
318 static SparcOperand *MorphToDoubleReg(SparcOperand *Op) {
319 unsigned Reg = Op->getReg();
320 assert(Op->Reg.Kind == rk_FloatReg);
321 unsigned regIdx = Reg - Sparc::F0;
322 if (regIdx % 2 || regIdx > 31)
324 Op->Reg.RegNum = DoubleRegs[regIdx / 2];
325 Op->Reg.Kind = rk_DoubleReg;
329 static SparcOperand *MorphToQuadReg(SparcOperand *Op) {
330 unsigned Reg = Op->getReg();
332 switch (Op->Reg.Kind) {
333 default: assert(0 && "Unexpected register kind!");
335 regIdx = Reg - Sparc::F0;
336 if (regIdx % 4 || regIdx > 31)
338 Reg = QuadFPRegs[regIdx / 4];
341 regIdx = Reg - Sparc::D0;
342 if (regIdx % 2 || regIdx > 31)
344 Reg = QuadFPRegs[regIdx / 2];
347 Op->Reg.RegNum = Reg;
348 Op->Reg.Kind = rk_QuadReg;
352 static SparcOperand *MorphToMEMrr(unsigned Base, SparcOperand *Op) {
353 unsigned offsetReg = Op->getReg();
354 Op->Kind = k_MemoryReg;
356 Op->Mem.OffsetReg = offsetReg;
361 static SparcOperand *CreateMEMri(unsigned Base,
364 SparcOperand *Op = new SparcOperand(k_MemoryImm);
366 Op->Mem.OffsetReg = 0;
373 static SparcOperand *MorphToMEMri(unsigned Base, SparcOperand *Op) {
374 const MCExpr *Imm = Op->getImm();
375 Op->Kind = k_MemoryImm;
377 Op->Mem.OffsetReg = 0;
385 bool SparcAsmParser::
386 MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
387 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
388 MCStreamer &Out, unsigned &ErrorInfo,
389 bool MatchingInlineAsm) {
391 SmallVector<MCInst, 8> Instructions;
392 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
394 switch (MatchResult) {
398 case Match_Success: {
400 Out.EmitInstruction(Inst, STI);
404 case Match_MissingFeature:
406 "instruction requires a CPU feature not currently enabled");
408 case Match_InvalidOperand: {
409 SMLoc ErrorLoc = IDLoc;
410 if (ErrorInfo != ~0U) {
411 if (ErrorInfo >= Operands.size())
412 return Error(IDLoc, "too few operands for instruction");
414 ErrorLoc = ((SparcOperand*) Operands[ErrorInfo])->getStartLoc();
415 if (ErrorLoc == SMLoc())
419 return Error(ErrorLoc, "invalid operand for instruction");
421 case Match_MnemonicFail:
422 return Error(IDLoc, "invalid instruction mnemonic");
427 bool SparcAsmParser::
428 ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc)
430 const AsmToken &Tok = Parser.getTok();
431 StartLoc = Tok.getLoc();
432 EndLoc = Tok.getEndLoc();
434 if (getLexer().getKind() != AsmToken::Percent)
437 unsigned regKind = SparcOperand::rk_None;
438 if (matchRegisterName(Tok, RegNo, regKind)) {
443 return Error(StartLoc, "invalid register name");
446 bool SparcAsmParser::
447 ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
449 SmallVectorImpl<MCParsedAsmOperand*> &Operands)
452 // First operand in MCInst is instruction mnemonic.
453 Operands.push_back(SparcOperand::CreateToken(Name, NameLoc));
455 if (getLexer().isNot(AsmToken::EndOfStatement)) {
456 // Read the first operand.
457 if (parseOperand(Operands, Name) != MatchOperand_Success) {
458 SMLoc Loc = getLexer().getLoc();
459 Parser.eatToEndOfStatement();
460 return Error(Loc, "unexpected token");
463 while (getLexer().is(AsmToken::Comma)) {
464 Parser.Lex(); // Eat the comma.
465 // Parse and remember the operand.
466 if (parseOperand(Operands, Name) != MatchOperand_Success) {
467 SMLoc Loc = getLexer().getLoc();
468 Parser.eatToEndOfStatement();
469 return Error(Loc, "unexpected token");
473 if (getLexer().isNot(AsmToken::EndOfStatement)) {
474 SMLoc Loc = getLexer().getLoc();
475 Parser.eatToEndOfStatement();
476 return Error(Loc, "unexpected token");
478 Parser.Lex(); // Consume the EndOfStatement.
482 bool SparcAsmParser::
483 ParseDirective(AsmToken DirectiveID)
485 StringRef IDVal = DirectiveID.getString();
487 if (IDVal == ".byte")
488 return parseDirectiveWord(1, DirectiveID.getLoc());
490 if (IDVal == ".half")
491 return parseDirectiveWord(2, DirectiveID.getLoc());
493 if (IDVal == ".word")
494 return parseDirectiveWord(4, DirectiveID.getLoc());
496 if (IDVal == ".nword")
497 return parseDirectiveWord(is64Bit() ? 8 : 4, DirectiveID.getLoc());
499 if (is64Bit() && IDVal == ".xword")
500 return parseDirectiveWord(8, DirectiveID.getLoc());
502 if (IDVal == ".register") {
503 // For now, ignore .register directive.
504 Parser.eatToEndOfStatement();
508 // Let the MC layer to handle other directives.
512 bool SparcAsmParser:: parseDirectiveWord(unsigned Size, SMLoc L) {
513 if (getLexer().isNot(AsmToken::EndOfStatement)) {
516 if (getParser().parseExpression(Value))
519 getParser().getStreamer().EmitValue(Value, Size);
521 if (getLexer().is(AsmToken::EndOfStatement))
524 // FIXME: Improve diagnostic.
525 if (getLexer().isNot(AsmToken::Comma))
526 return Error(L, "unexpected token in directive");
534 SparcAsmParser::OperandMatchResultTy SparcAsmParser::
535 parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands)
539 unsigned BaseReg = 0;
541 if (ParseRegister(BaseReg, S, E)) {
542 return MatchOperand_NoMatch;
545 switch (getLexer().getKind()) {
546 default: return MatchOperand_NoMatch;
548 case AsmToken::Comma:
549 case AsmToken::RBrac:
550 case AsmToken::EndOfStatement:
551 Operands.push_back(SparcOperand::CreateMEMri(BaseReg, 0, S, E));
552 return MatchOperand_Success;
554 case AsmToken:: Plus:
555 Parser.Lex(); // Eat the '+'
557 case AsmToken::Minus:
561 SparcOperand *Offset = 0;
562 OperandMatchResultTy ResTy = parseSparcAsmOperand(Offset);
563 if (ResTy != MatchOperand_Success || !Offset)
564 return MatchOperand_NoMatch;
566 Offset = (Offset->isImm()
567 ? SparcOperand::MorphToMEMri(BaseReg, Offset)
568 : SparcOperand::MorphToMEMrr(BaseReg, Offset));
570 Operands.push_back(Offset);
571 return MatchOperand_Success;
574 SparcAsmParser::OperandMatchResultTy SparcAsmParser::
575 parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
579 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
581 // If there wasn't a custom match, try the generic matcher below. Otherwise,
582 // there was a match, but an error occurred, in which case, just return that
583 // the operand parsing failed.
584 if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail)
587 if (getLexer().is(AsmToken::LBrac)) {
589 Operands.push_back(SparcOperand::CreateToken("[",
590 Parser.getTok().getLoc()));
591 Parser.Lex(); // Eat the [
593 if (Mnemonic == "cas" || Mnemonic == "casx") {
594 SMLoc S = Parser.getTok().getLoc();
595 if (getLexer().getKind() != AsmToken::Percent)
596 return MatchOperand_NoMatch;
597 Parser.Lex(); // eat %
599 unsigned RegNo, RegKind;
600 if (!matchRegisterName(Parser.getTok(), RegNo, RegKind))
601 return MatchOperand_NoMatch;
603 Parser.Lex(); // Eat the identifier token.
604 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer()-1);
605 Operands.push_back(SparcOperand::CreateReg(RegNo, RegKind, S, E));
606 ResTy = MatchOperand_Success;
608 ResTy = parseMEMOperand(Operands);
611 if (ResTy != MatchOperand_Success)
614 if (!getLexer().is(AsmToken::RBrac))
615 return MatchOperand_ParseFail;
617 Operands.push_back(SparcOperand::CreateToken("]",
618 Parser.getTok().getLoc()));
619 Parser.Lex(); // Eat the ]
620 return MatchOperand_Success;
623 SparcOperand *Op = 0;
624 ResTy = parseSparcAsmOperand(Op, (Mnemonic == "call"));
625 if (ResTy != MatchOperand_Success || !Op)
626 return MatchOperand_ParseFail;
628 // Push the parsed operand into the list of operands
629 Operands.push_back(Op);
631 return MatchOperand_Success;
634 SparcAsmParser::OperandMatchResultTy
635 SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op, bool isCall)
638 SMLoc S = Parser.getTok().getLoc();
639 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
643 switch (getLexer().getKind()) {
646 case AsmToken::Percent:
647 Parser.Lex(); // Eat the '%'.
650 if (matchRegisterName(Parser.getTok(), RegNo, RegKind)) {
651 StringRef name = Parser.getTok().getString();
652 Parser.Lex(); // Eat the identifier token.
653 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
656 Op = SparcOperand::CreateReg(RegNo, RegKind, S, E);
659 Op = SparcOperand::CreateToken("%y", S);
664 Op = SparcOperand::CreateToken("%xcc", S);
666 Op = SparcOperand::CreateToken("%icc", S);
670 assert(name == "fcc0" && "Cannot handle %fcc other than %fcc0 yet");
671 Op = SparcOperand::CreateToken("%fcc0", S);
676 if (matchSparcAsmModifiers(EVal, E)) {
677 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
678 Op = SparcOperand::CreateImm(EVal, S, E);
682 case AsmToken::Minus:
683 case AsmToken::Integer:
684 if (!getParser().parseExpression(EVal, E))
685 Op = SparcOperand::CreateImm(EVal, S, E);
688 case AsmToken::Identifier: {
689 StringRef Identifier;
690 if (!getParser().parseIdentifier(Identifier)) {
691 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
692 MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier);
694 const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
697 getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_)
698 Res = SparcMCExpr::Create(SparcMCExpr::VK_Sparc_WPLT30, Res,
700 Op = SparcOperand::CreateImm(Res, S, E);
705 return (Op) ? MatchOperand_Success : MatchOperand_ParseFail;
708 bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
714 RegKind = SparcOperand::rk_None;
715 if (Tok.is(AsmToken::Identifier)) {
716 StringRef name = Tok.getString();
719 if (name.equals("fp")) {
721 RegKind = SparcOperand::rk_IntReg;
725 if (name.equals("sp")) {
727 RegKind = SparcOperand::rk_IntReg;
731 if (name.equals("y")) {
733 RegKind = SparcOperand::rk_Y;
737 if (name.equals("icc")) {
739 RegKind = SparcOperand::rk_CCReg;
743 if (name.equals("xcc")) {
744 // FIXME:: check 64bit.
746 RegKind = SparcOperand::rk_CCReg;
751 if (name.substr(0, 3).equals_lower("fcc")
752 && !name.substr(3).getAsInteger(10, intVal)
754 // FIXME: check 64bit and handle %fcc1 - %fcc3
756 RegKind = SparcOperand::rk_CCReg;
761 if (name.substr(0, 1).equals_lower("g")
762 && !name.substr(1).getAsInteger(10, intVal)
764 RegNo = IntRegs[intVal];
765 RegKind = SparcOperand::rk_IntReg;
769 if (name.substr(0, 1).equals_lower("o")
770 && !name.substr(1).getAsInteger(10, intVal)
772 RegNo = IntRegs[8 + intVal];
773 RegKind = SparcOperand::rk_IntReg;
776 if (name.substr(0, 1).equals_lower("l")
777 && !name.substr(1).getAsInteger(10, intVal)
779 RegNo = IntRegs[16 + intVal];
780 RegKind = SparcOperand::rk_IntReg;
783 if (name.substr(0, 1).equals_lower("i")
784 && !name.substr(1).getAsInteger(10, intVal)
786 RegNo = IntRegs[24 + intVal];
787 RegKind = SparcOperand::rk_IntReg;
791 if (name.substr(0, 1).equals_lower("f")
792 && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 32) {
793 RegNo = FloatRegs[intVal];
794 RegKind = SparcOperand::rk_FloatReg;
798 if (name.substr(0, 1).equals_lower("f")
799 && !name.substr(1, 2).getAsInteger(10, intVal)
800 && intVal >= 32 && intVal <= 62 && (intVal % 2 == 0)) {
802 RegNo = DoubleRegs[intVal/2];
803 RegKind = SparcOperand::rk_DoubleReg;
808 if (name.substr(0, 1).equals_lower("r")
809 && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) {
810 RegNo = IntRegs[intVal];
811 RegKind = SparcOperand::rk_IntReg;
818 static bool hasGOTReference(const MCExpr *Expr) {
819 switch (Expr->getKind()) {
821 if (const SparcMCExpr *SE = dyn_cast<SparcMCExpr>(Expr))
822 return hasGOTReference(SE->getSubExpr());
825 case MCExpr::Constant:
828 case MCExpr::Binary: {
829 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
830 return hasGOTReference(BE->getLHS()) || hasGOTReference(BE->getRHS());
833 case MCExpr::SymbolRef: {
834 const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
835 return (SymRef.getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_");
839 return hasGOTReference(cast<MCUnaryExpr>(Expr)->getSubExpr());
844 bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
847 AsmToken Tok = Parser.getTok();
848 if (!Tok.is(AsmToken::Identifier))
851 StringRef name = Tok.getString();
853 SparcMCExpr::VariantKind VK = SparcMCExpr::parseVariantKind(name);
855 if (VK == SparcMCExpr::VK_Sparc_None)
858 Parser.Lex(); // Eat the identifier.
859 if (Parser.getTok().getKind() != AsmToken::LParen)
862 Parser.Lex(); // Eat the LParen token.
863 const MCExpr *subExpr;
864 if (Parser.parseParenExpression(subExpr, EndLoc))
867 bool isPIC = getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_;
871 case SparcMCExpr::VK_Sparc_LO:
872 VK = (hasGOTReference(subExpr)
873 ? SparcMCExpr::VK_Sparc_PC10
874 : (isPIC ? SparcMCExpr::VK_Sparc_GOT10 : VK));
876 case SparcMCExpr::VK_Sparc_HI:
877 VK = (hasGOTReference(subExpr)
878 ? SparcMCExpr::VK_Sparc_PC22
879 : (isPIC ? SparcMCExpr::VK_Sparc_GOT22 : VK));
883 EVal = SparcMCExpr::Create(VK, subExpr, getContext());
888 extern "C" void LLVMInitializeSparcAsmParser() {
889 RegisterMCAsmParser<SparcAsmParser> A(TheSparcTarget);
890 RegisterMCAsmParser<SparcAsmParser> B(TheSparcV9Target);
893 #define GET_REGISTER_MATCHER
894 #define GET_MATCHER_IMPLEMENTATION
895 #include "SparcGenAsmMatcher.inc"
899 unsigned SparcAsmParser::
900 validateTargetOperandClass(MCParsedAsmOperand *GOp,
903 SparcOperand *Op = (SparcOperand*)GOp;
904 if (Op->isFloatOrDoubleReg()) {
908 if (!Op->isFloatReg() || SparcOperand::MorphToDoubleReg(Op))
909 return MCTargetAsmParser::Match_Success;
912 if (SparcOperand::MorphToQuadReg(Op))
913 return MCTargetAsmParser::Match_Success;
917 return Match_InvalidOperand;