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/MCParser/MCParsedAsmOperand.h"
16 #include "llvm/MC/MCStreamer.h"
17 #include "llvm/MC/MCSubtargetInfo.h"
18 #include "llvm/MC/MCTargetAsmParser.h"
19 #include "llvm/Support/TargetRegistry.h"
23 // The generated AsmMatcher SparcGenAsmMatcher uses "Sparc" as the target
24 // namespace. But SPARC backend uses "SP" as its namespace.
33 class SparcAsmParser : public MCTargetAsmParser {
38 /// @name Auto-generated Match Functions
41 #define GET_ASSEMBLER_HEADER
42 #include "SparcGenAsmMatcher.inc"
46 // public interface of the MCTargetAsmParser.
47 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
48 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
49 MCStreamer &Out, unsigned &ErrorInfo,
50 bool MatchingInlineAsm);
51 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
52 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
54 SmallVectorImpl<MCParsedAsmOperand*> &Operands);
55 bool ParseDirective(AsmToken DirectiveID);
57 virtual unsigned validateTargetOperandClass(MCParsedAsmOperand *Op,
60 // Custom parse functions for Sparc specific operands.
62 parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
65 parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
69 parseSparcAsmOperand(SparcOperand *&Operand);
71 // returns true if Tok is matched to a register and returns register in RegNo.
72 bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo,
75 bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc);
78 SparcAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
79 const MCInstrInfo &MII)
80 : MCTargetAsmParser(), STI(sti), Parser(parser) {
81 // Initialize the set of available features.
82 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
87 static unsigned IntRegs[32] = {
88 Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,
89 Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,
90 Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,
91 Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,
92 Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,
93 Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,
94 Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,
95 Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };
97 static unsigned FloatRegs[32] = {
98 Sparc::F0, Sparc::F1, Sparc::F2, Sparc::F3,
99 Sparc::F4, Sparc::F5, Sparc::F6, Sparc::F7,
100 Sparc::F8, Sparc::F9, Sparc::F10, Sparc::F11,
101 Sparc::F12, Sparc::F13, Sparc::F14, Sparc::F15,
102 Sparc::F16, Sparc::F17, Sparc::F18, Sparc::F19,
103 Sparc::F20, Sparc::F21, Sparc::F22, Sparc::F23,
104 Sparc::F24, Sparc::F25, Sparc::F26, Sparc::F27,
105 Sparc::F28, Sparc::F29, Sparc::F30, Sparc::F31 };
107 static unsigned DoubleRegs[32] = {
108 Sparc::D0, Sparc::D1, Sparc::D2, Sparc::D3,
109 Sparc::D4, Sparc::D5, Sparc::D6, Sparc::D7,
110 Sparc::D8, Sparc::D7, Sparc::D8, Sparc::D9,
111 Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,
112 Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,
113 Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,
114 Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,
115 Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };
117 static unsigned QuadFPRegs[32] = {
118 Sparc::Q0, Sparc::Q1, Sparc::Q2, Sparc::Q3,
119 Sparc::Q4, Sparc::Q5, Sparc::Q6, Sparc::Q7,
120 Sparc::Q8, Sparc::Q7, Sparc::Q8, Sparc::Q9,
121 Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
124 /// SparcOperand - Instances of this class represent a parsed Sparc machine
126 class SparcOperand : public MCParsedAsmOperand {
146 SMLoc StartLoc, EndLoc;
148 SparcOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
177 bool isToken() const { return Kind == k_Token; }
178 bool isReg() const { return Kind == k_Register; }
179 bool isImm() const { return Kind == k_Immediate; }
180 bool isMem() const { return isMEMrr() || isMEMri(); }
181 bool isMEMrr() const { return Kind == k_MemoryReg; }
182 bool isMEMri() const { return Kind == k_MemoryImm; }
184 bool isFloatReg() const {
185 return (Kind == k_Register && Reg.Kind == rk_FloatReg);
188 bool isFloatOrDoubleReg() const {
189 return (Kind == k_Register && (Reg.Kind == rk_FloatReg
190 || Reg.Kind == rk_DoubleReg));
194 StringRef getToken() const {
195 assert(Kind == k_Token && "Invalid access!");
196 return StringRef(Tok.Data, Tok.Length);
199 unsigned getReg() const {
200 assert((Kind == k_Register) && "Invalid access!");
204 const MCExpr *getImm() const {
205 assert((Kind == k_Immediate) && "Invalid access!");
209 unsigned getMemBase() const {
210 assert((Kind == k_MemoryReg || Kind == k_MemoryImm) && "Invalid access!");
214 unsigned getMemOffsetReg() const {
215 assert((Kind == k_MemoryReg) && "Invalid access!");
216 return Mem.OffsetReg;
219 const MCExpr *getMemOff() const {
220 assert((Kind == k_MemoryImm) && "Invalid access!");
224 /// getStartLoc - Get the location of the first token of this operand.
225 SMLoc getStartLoc() const {
228 /// getEndLoc - Get the location of the last token of this operand.
229 SMLoc getEndLoc() const {
233 virtual void print(raw_ostream &OS) const {
235 case k_Token: OS << "Token: " << getToken() << "\n"; break;
236 case k_Register: OS << "Reg: #" << getReg() << "\n"; break;
237 case k_Immediate: OS << "Imm: " << getImm() << "\n"; break;
238 case k_MemoryReg: OS << "Mem: " << getMemBase() << "+"
239 << getMemOffsetReg() << "\n"; break;
240 case k_MemoryImm: assert(getMemOff() != 0);
241 OS << "Mem: " << getMemBase()
242 << "+" << *getMemOff()
247 void addRegOperands(MCInst &Inst, unsigned N) const {
248 assert(N == 1 && "Invalid number of operands!");
249 Inst.addOperand(MCOperand::CreateReg(getReg()));
252 void addImmOperands(MCInst &Inst, unsigned N) const {
253 assert(N == 1 && "Invalid number of operands!");
254 const MCExpr *Expr = getImm();
258 void addExpr(MCInst &Inst, const MCExpr *Expr) const{
259 // Add as immediate when possible. Null MCExpr = 0.
261 Inst.addOperand(MCOperand::CreateImm(0));
262 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
263 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
265 Inst.addOperand(MCOperand::CreateExpr(Expr));
268 void addMEMrrOperands(MCInst &Inst, unsigned N) const {
269 assert(N == 2 && "Invalid number of operands!");
271 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
273 assert(getMemOffsetReg() != 0 && "Invalid offset");
274 Inst.addOperand(MCOperand::CreateReg(getMemOffsetReg()));
277 void addMEMriOperands(MCInst &Inst, unsigned N) const {
278 assert(N == 2 && "Invalid number of operands!");
280 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
282 const MCExpr *Expr = getMemOff();
286 static SparcOperand *CreateToken(StringRef Str, SMLoc S) {
287 SparcOperand *Op = new SparcOperand(k_Token);
288 Op->Tok.Data = Str.data();
289 Op->Tok.Length = Str.size();
295 static SparcOperand *CreateReg(unsigned RegNum,
298 SparcOperand *Op = new SparcOperand(k_Register);
299 Op->Reg.RegNum = RegNum;
300 Op->Reg.Kind = (SparcOperand::RegisterKind)Kind;
306 static SparcOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
307 SparcOperand *Op = new SparcOperand(k_Immediate);
314 static SparcOperand *MorphToDoubleReg(SparcOperand *Op) {
315 unsigned Reg = Op->getReg();
316 assert(Op->Reg.Kind == rk_FloatReg);
317 unsigned regIdx = Reg - Sparc::F0;
318 if (regIdx % 2 || regIdx > 31)
320 Op->Reg.RegNum = DoubleRegs[regIdx / 2];
321 Op->Reg.Kind = rk_DoubleReg;
325 static SparcOperand *MorphToQuadReg(SparcOperand *Op) {
326 unsigned Reg = Op->getReg();
328 switch (Op->Reg.Kind) {
329 default: assert(0 && "Unexpected register kind!");
331 regIdx = Reg - Sparc::F0;
332 if (regIdx % 4 || regIdx > 31)
334 Reg = QuadFPRegs[regIdx / 4];
337 regIdx = Reg - Sparc::D0;
338 if (regIdx % 2 || regIdx > 31)
340 Reg = QuadFPRegs[regIdx / 2];
343 Op->Reg.RegNum = Reg;
344 Op->Reg.Kind = rk_QuadReg;
348 static SparcOperand *MorphToMEMrr(unsigned Base, SparcOperand *Op) {
349 unsigned offsetReg = Op->getReg();
350 Op->Kind = k_MemoryReg;
352 Op->Mem.OffsetReg = offsetReg;
357 static SparcOperand *CreateMEMri(unsigned Base,
360 SparcOperand *Op = new SparcOperand(k_MemoryImm);
362 Op->Mem.OffsetReg = 0;
369 static SparcOperand *MorphToMEMri(unsigned Base, SparcOperand *Op) {
370 const MCExpr *Imm = Op->getImm();
371 Op->Kind = k_MemoryImm;
373 Op->Mem.OffsetReg = 0;
381 bool SparcAsmParser::
382 MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
383 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
384 MCStreamer &Out, unsigned &ErrorInfo,
385 bool MatchingInlineAsm) {
387 SmallVector<MCInst, 8> Instructions;
388 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
390 switch (MatchResult) {
394 case Match_Success: {
396 Out.EmitInstruction(Inst);
400 case Match_MissingFeature:
402 "instruction requires a CPU feature not currently enabled");
404 case Match_InvalidOperand: {
405 SMLoc ErrorLoc = IDLoc;
406 if (ErrorInfo != ~0U) {
407 if (ErrorInfo >= Operands.size())
408 return Error(IDLoc, "too few operands for instruction");
410 ErrorLoc = ((SparcOperand*) Operands[ErrorInfo])->getStartLoc();
411 if (ErrorLoc == SMLoc())
415 return Error(ErrorLoc, "invalid operand for instruction");
417 case Match_MnemonicFail:
418 return Error(IDLoc, "invalid instruction");
423 bool SparcAsmParser::
424 ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc)
426 const AsmToken &Tok = Parser.getTok();
427 StartLoc = Tok.getLoc();
428 EndLoc = Tok.getEndLoc();
430 if (getLexer().getKind() != AsmToken::Percent)
433 unsigned regKind = SparcOperand::rk_None;
434 if (matchRegisterName(Tok, RegNo, regKind)) {
439 return Error(StartLoc, "invalid register name");
442 bool SparcAsmParser::
443 ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
445 SmallVectorImpl<MCParsedAsmOperand*> &Operands)
447 // Check if we have valid mnemonic.
448 if (!mnemonicIsValid(Name, 0)) {
449 Parser.eatToEndOfStatement();
450 return Error(NameLoc, "Unknown instruction");
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 // Ignore all directives for now.
486 Parser.eatToEndOfStatement();
490 SparcAsmParser::OperandMatchResultTy SparcAsmParser::
491 parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands)
495 unsigned BaseReg = 0;
497 if (ParseRegister(BaseReg, S, E)) {
498 return MatchOperand_NoMatch;
501 switch (getLexer().getKind()) {
502 default: return MatchOperand_NoMatch;
504 case AsmToken::Comma:
505 case AsmToken::RBrac:
506 case AsmToken::EndOfStatement:
507 Operands.push_back(SparcOperand::CreateMEMri(BaseReg, 0, S, E));
508 return MatchOperand_Success;
510 case AsmToken:: Plus:
511 Parser.Lex(); // Eat the '+'
513 case AsmToken::Minus:
517 SparcOperand *Offset = 0;
518 OperandMatchResultTy ResTy = parseSparcAsmOperand(Offset);
519 if (ResTy != MatchOperand_Success || !Offset)
520 return MatchOperand_NoMatch;
522 Offset = (Offset->isImm()
523 ? SparcOperand::MorphToMEMri(BaseReg, Offset)
524 : SparcOperand::MorphToMEMrr(BaseReg, Offset));
526 Operands.push_back(Offset);
527 return MatchOperand_Success;
530 SparcAsmParser::OperandMatchResultTy SparcAsmParser::
531 parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
535 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
537 // If there wasn't a custom match, try the generic matcher below. Otherwise,
538 // there was a match, but an error occurred, in which case, just return that
539 // the operand parsing failed.
540 if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail)
543 if (getLexer().is(AsmToken::LBrac)) {
545 Operands.push_back(SparcOperand::CreateToken("[",
546 Parser.getTok().getLoc()));
547 Parser.Lex(); // Eat the [
549 ResTy = parseMEMOperand(Operands);
550 if (ResTy != MatchOperand_Success)
553 if (!getLexer().is(AsmToken::RBrac))
554 return MatchOperand_ParseFail;
556 Operands.push_back(SparcOperand::CreateToken("]",
557 Parser.getTok().getLoc()));
558 Parser.Lex(); // Eat the ]
559 return MatchOperand_Success;
562 SparcOperand *Op = 0;
563 ResTy = parseSparcAsmOperand(Op);
564 if (ResTy != MatchOperand_Success || !Op)
565 return MatchOperand_ParseFail;
567 // Push the parsed operand into the list of operands
568 Operands.push_back(Op);
570 return MatchOperand_Success;
573 SparcAsmParser::OperandMatchResultTy
574 SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op)
577 SMLoc S = Parser.getTok().getLoc();
578 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
582 switch (getLexer().getKind()) {
585 case AsmToken::Percent:
586 Parser.Lex(); // Eat the '%'.
589 if (matchRegisterName(Parser.getTok(), RegNo, RegKind)) {
590 StringRef name = Parser.getTok().getString();
591 Parser.Lex(); // Eat the identifier token.
592 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
595 Op = SparcOperand::CreateReg(RegNo, RegKind, S, E);
598 Op = SparcOperand::CreateToken("%y", S);
603 Op = SparcOperand::CreateToken("%xcc", S);
605 Op = SparcOperand::CreateToken("%icc", S);
609 assert(name == "fcc0" && "Cannot handle %fcc other than %fcc0 yet");
610 Op = SparcOperand::CreateToken("%fcc0", S);
615 if (matchSparcAsmModifiers(EVal, E)) {
616 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
617 Op = SparcOperand::CreateImm(EVal, S, E);
621 case AsmToken::Minus:
622 case AsmToken::Integer:
623 if (!getParser().parseExpression(EVal, E))
624 Op = SparcOperand::CreateImm(EVal, S, E);
627 case AsmToken::Identifier: {
628 StringRef Identifier;
629 if (!getParser().parseIdentifier(Identifier)) {
630 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
631 MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier);
633 const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
635 Op = SparcOperand::CreateImm(Res, S, E);
640 return (Op) ? MatchOperand_Success : MatchOperand_ParseFail;
643 bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
649 RegKind = SparcOperand::rk_None;
650 if (Tok.is(AsmToken::Identifier)) {
651 StringRef name = Tok.getString();
654 if (name.equals("fp")) {
656 RegKind = SparcOperand::rk_IntReg;
660 if (name.equals("sp")) {
662 RegKind = SparcOperand::rk_IntReg;
666 if (name.equals("y")) {
668 RegKind = SparcOperand::rk_Y;
672 if (name.equals("icc")) {
674 RegKind = SparcOperand::rk_CCReg;
678 if (name.equals("xcc")) {
679 // FIXME:: check 64bit.
681 RegKind = SparcOperand::rk_CCReg;
686 if (name.substr(0, 3).equals_lower("fcc")
687 && !name.substr(3).getAsInteger(10, intVal)
689 // FIXME: check 64bit and handle %fcc1 - %fcc3
691 RegKind = SparcOperand::rk_CCReg;
696 if (name.substr(0, 1).equals_lower("g")
697 && !name.substr(1).getAsInteger(10, intVal)
699 RegNo = IntRegs[intVal];
700 RegKind = SparcOperand::rk_IntReg;
704 if (name.substr(0, 1).equals_lower("o")
705 && !name.substr(1).getAsInteger(10, intVal)
707 RegNo = IntRegs[8 + intVal];
708 RegKind = SparcOperand::rk_IntReg;
711 if (name.substr(0, 1).equals_lower("l")
712 && !name.substr(1).getAsInteger(10, intVal)
714 RegNo = IntRegs[16 + intVal];
715 RegKind = SparcOperand::rk_IntReg;
718 if (name.substr(0, 1).equals_lower("i")
719 && !name.substr(1).getAsInteger(10, intVal)
721 RegNo = IntRegs[24 + intVal];
722 RegKind = SparcOperand::rk_IntReg;
726 if (name.substr(0, 1).equals_lower("f")
727 && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 32) {
728 RegNo = FloatRegs[intVal];
729 RegKind = SparcOperand::rk_FloatReg;
733 if (name.substr(0, 1).equals_lower("f")
734 && !name.substr(1, 2).getAsInteger(10, intVal)
735 && intVal >= 32 && intVal <= 62 && (intVal % 2 == 0)) {
737 RegNo = DoubleRegs[intVal/2];
738 RegKind = SparcOperand::rk_DoubleReg;
743 if (name.substr(0, 1).equals_lower("r")
744 && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) {
745 RegNo = IntRegs[intVal];
746 RegKind = SparcOperand::rk_IntReg;
754 bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
757 AsmToken Tok = Parser.getTok();
758 if (!Tok.is(AsmToken::Identifier))
761 StringRef name = Tok.getString();
763 SparcMCExpr::VariantKind VK = SparcMCExpr::parseVariantKind(name);
765 if (VK == SparcMCExpr::VK_Sparc_None)
768 Parser.Lex(); // Eat the identifier.
769 if (Parser.getTok().getKind() != AsmToken::LParen)
772 Parser.Lex(); // Eat the LParen token.
773 const MCExpr *subExpr;
774 if (Parser.parseParenExpression(subExpr, EndLoc))
776 EVal = SparcMCExpr::Create(VK, subExpr, getContext());
781 extern "C" void LLVMInitializeSparcAsmParser() {
782 RegisterMCAsmParser<SparcAsmParser> A(TheSparcTarget);
783 RegisterMCAsmParser<SparcAsmParser> B(TheSparcV9Target);
786 #define GET_REGISTER_MATCHER
787 #define GET_MATCHER_IMPLEMENTATION
788 #include "SparcGenAsmMatcher.inc"
792 unsigned SparcAsmParser::
793 validateTargetOperandClass(MCParsedAsmOperand *GOp,
796 SparcOperand *Op = (SparcOperand*)GOp;
797 if (Op->isFloatOrDoubleReg()) {
801 if (!Op->isFloatReg() || SparcOperand::MorphToDoubleReg(Op))
802 return MCTargetAsmParser::Match_Success;
805 if (SparcOperand::MorphToQuadReg(Op))
806 return MCTargetAsmParser::Match_Success;
810 return Match_InvalidOperand;