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 "llvm/ADT/STLExtras.h"
12 #include "llvm/MC/MCContext.h"
13 #include "llvm/MC/MCInst.h"
14 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
15 #include "llvm/MC/MCStreamer.h"
16 #include "llvm/MC/MCSubtargetInfo.h"
17 #include "llvm/MC/MCTargetAsmParser.h"
18 #include "llvm/Support/TargetRegistry.h"
22 // The generated AsmMatcher SparcGenAsmMatcher uses "Sparc" as the target
23 // namespace. But SPARC backend uses "SP" as its namespace.
32 class SparcAsmParser : public MCTargetAsmParser {
37 /// @name Auto-generated Match Functions
40 #define GET_ASSEMBLER_HEADER
41 #include "SparcGenAsmMatcher.inc"
45 // public interface of the MCTargetAsmParser.
46 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
47 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
48 MCStreamer &Out, unsigned &ErrorInfo,
49 bool MatchingInlineAsm);
50 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
51 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
53 SmallVectorImpl<MCParsedAsmOperand*> &Operands);
54 bool ParseDirective(AsmToken DirectiveID);
57 // Custom parse functions for Sparc specific operands.
59 parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
62 parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
66 parseSparcAsmOperand(SparcOperand *&Operand);
68 // returns true if Tok is matched to a register and returns register in RegNo.
69 bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo, bool isDFP,
73 SparcAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
74 const MCInstrInfo &MII)
75 : MCTargetAsmParser(), STI(sti), Parser(parser) {
76 // Initialize the set of available features.
77 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
82 static unsigned IntRegs[32] = {
83 Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,
84 Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,
85 Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,
86 Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,
87 Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,
88 Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,
89 Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,
90 Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };
92 static unsigned FloatRegs[32] = {
93 Sparc::F0, Sparc::F1, Sparc::F2, Sparc::F3,
94 Sparc::F4, Sparc::F5, Sparc::F6, Sparc::F7,
95 Sparc::F8, Sparc::F9, Sparc::F10, Sparc::F11,
96 Sparc::F12, Sparc::F13, Sparc::F14, Sparc::F15,
97 Sparc::F16, Sparc::F17, Sparc::F18, Sparc::F19,
98 Sparc::F20, Sparc::F21, Sparc::F22, Sparc::F23,
99 Sparc::F24, Sparc::F25, Sparc::F26, Sparc::F27,
100 Sparc::F28, Sparc::F29, Sparc::F30, Sparc::F31 };
102 static unsigned DoubleRegs[32] = {
103 Sparc::D0, Sparc::D1, Sparc::D2, Sparc::D3,
104 Sparc::D4, Sparc::D5, Sparc::D6, Sparc::D7,
105 Sparc::D8, Sparc::D7, Sparc::D8, Sparc::D9,
106 Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,
107 Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,
108 Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,
109 Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,
110 Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };
112 static unsigned QuadFPRegs[32] = {
113 Sparc::Q0, Sparc::Q1, Sparc::Q2, Sparc::Q3,
114 Sparc::Q4, Sparc::Q5, Sparc::Q6, Sparc::Q7,
115 Sparc::Q8, Sparc::Q7, Sparc::Q8, Sparc::Q9,
116 Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
119 /// SparcOperand - Instances of this class represent a parsed Sparc machine
121 class SparcOperand : public MCParsedAsmOperand {
141 SMLoc StartLoc, EndLoc;
143 SparcOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
172 bool isToken() const { return Kind == k_Token; }
173 bool isReg() const { return Kind == k_Register; }
174 bool isImm() const { return Kind == k_Immediate; }
175 bool isMem() const { return isMEMrr() || isMEMri(); }
176 bool isMEMrr() const { return Kind == k_MemoryReg; }
177 bool isMEMri() const { return Kind == k_MemoryImm; }
179 StringRef getToken() const {
180 assert(Kind == k_Token && "Invalid access!");
181 return StringRef(Tok.Data, Tok.Length);
184 unsigned getReg() const {
185 assert((Kind == k_Register) && "Invalid access!");
189 const MCExpr *getImm() const {
190 assert((Kind == k_Immediate) && "Invalid access!");
194 unsigned getMemBase() const {
195 assert((Kind == k_MemoryReg || Kind == k_MemoryImm) && "Invalid access!");
199 unsigned getMemOffsetReg() const {
200 assert((Kind == k_MemoryReg) && "Invalid access!");
201 return Mem.OffsetReg;
204 const MCExpr *getMemOff() const {
205 assert((Kind == k_MemoryImm) && "Invalid access!");
209 /// getStartLoc - Get the location of the first token of this operand.
210 SMLoc getStartLoc() const {
213 /// getEndLoc - Get the location of the last token of this operand.
214 SMLoc getEndLoc() const {
218 virtual void print(raw_ostream &OS) const {
220 case k_Token: OS << "Token: " << getToken() << "\n"; break;
221 case k_Register: OS << "Reg: #" << getReg() << "\n"; break;
222 case k_Immediate: OS << "Imm: " << getImm() << "\n"; break;
223 case k_MemoryReg: OS << "Mem: " << getMemBase() << "+"
224 << getMemOffsetReg() << "\n"; break;
225 case k_MemoryImm: assert(getMemOff() != 0);
226 OS << "Mem: " << getMemBase()
227 << "+" << *getMemOff()
232 void addRegOperands(MCInst &Inst, unsigned N) const {
233 assert(N == 1 && "Invalid number of operands!");
234 Inst.addOperand(MCOperand::CreateReg(getReg()));
237 void addImmOperands(MCInst &Inst, unsigned N) const {
238 assert(N == 1 && "Invalid number of operands!");
239 const MCExpr *Expr = getImm();
243 void addExpr(MCInst &Inst, const MCExpr *Expr) const{
244 // Add as immediate when possible. Null MCExpr = 0.
246 Inst.addOperand(MCOperand::CreateImm(0));
247 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
248 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
250 Inst.addOperand(MCOperand::CreateExpr(Expr));
253 void addMEMrrOperands(MCInst &Inst, unsigned N) const {
254 assert(N == 2 && "Invalid number of operands!");
256 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
258 assert(getMemOffsetReg() != 0 && "Invalid offset");
259 Inst.addOperand(MCOperand::CreateReg(getMemOffsetReg()));
262 void addMEMriOperands(MCInst &Inst, unsigned N) const {
263 assert(N == 2 && "Invalid number of operands!");
265 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
267 const MCExpr *Expr = getMemOff();
271 static SparcOperand *CreateToken(StringRef Str, SMLoc S) {
272 SparcOperand *Op = new SparcOperand(k_Token);
273 Op->Tok.Data = Str.data();
274 Op->Tok.Length = Str.size();
280 static SparcOperand *CreateReg(unsigned RegNum,
281 SparcOperand::RegisterKind Kind,
283 SparcOperand *Op = new SparcOperand(k_Register);
284 Op->Reg.RegNum = RegNum;
291 static SparcOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
292 SparcOperand *Op = new SparcOperand(k_Immediate);
299 static SparcOperand *MorphToMEMrr(unsigned Base, SparcOperand *Op) {
300 unsigned offsetReg = Op->getReg();
301 Op->Kind = k_MemoryReg;
303 Op->Mem.OffsetReg = offsetReg;
308 static SparcOperand *CreateMEMri(unsigned Base,
311 SparcOperand *Op = new SparcOperand(k_MemoryImm);
313 Op->Mem.OffsetReg = 0;
320 static SparcOperand *MorphToMEMri(unsigned Base, SparcOperand *Op) {
321 const MCExpr *Imm = Op->getImm();
322 Op->Kind = k_MemoryImm;
324 Op->Mem.OffsetReg = 0;
332 bool SparcAsmParser::
333 MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
334 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
335 MCStreamer &Out, unsigned &ErrorInfo,
336 bool MatchingInlineAsm) {
338 SmallVector<MCInst, 8> Instructions;
339 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
341 switch (MatchResult) {
345 case Match_Success: {
347 Out.EmitInstruction(Inst);
351 case Match_MissingFeature:
353 "instruction requires a CPU feature not currently enabled");
355 case Match_InvalidOperand: {
356 SMLoc ErrorLoc = IDLoc;
357 if (ErrorInfo != ~0U) {
358 if (ErrorInfo >= Operands.size())
359 return Error(IDLoc, "too few operands for instruction");
361 ErrorLoc = ((SparcOperand*) Operands[ErrorInfo])->getStartLoc();
362 if (ErrorLoc == SMLoc())
366 return Error(ErrorLoc, "invalid operand for instruction");
368 case Match_MnemonicFail:
369 return Error(IDLoc, "invalid instruction");
374 bool SparcAsmParser::
375 ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc)
377 const AsmToken &Tok = Parser.getTok();
378 StartLoc = Tok.getLoc();
379 EndLoc = Tok.getEndLoc();
381 if (getLexer().getKind() != AsmToken::Percent)
384 if (matchRegisterName(Tok, RegNo, false, false)) {
389 return Error(StartLoc, "invalid register name");
392 bool SparcAsmParser::
393 ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
395 SmallVectorImpl<MCParsedAsmOperand*> &Operands)
397 // Check if we have valid mnemonic.
398 if (!mnemonicIsValid(Name, 0)) {
399 Parser.eatToEndOfStatement();
400 return Error(NameLoc, "Unknown instruction");
402 // First operand in MCInst is instruction mnemonic.
403 Operands.push_back(SparcOperand::CreateToken(Name, NameLoc));
405 if (getLexer().isNot(AsmToken::EndOfStatement)) {
406 // Read the first operand.
407 if (parseOperand(Operands, Name) != MatchOperand_Success) {
408 SMLoc Loc = getLexer().getLoc();
409 Parser.eatToEndOfStatement();
410 return Error(Loc, "unexpected token");
413 while (getLexer().is(AsmToken::Comma)) {
414 Parser.Lex(); // Eat the comma.
415 // Parse and remember the operand.
416 if (parseOperand(Operands, Name) != MatchOperand_Success) {
417 SMLoc Loc = getLexer().getLoc();
418 Parser.eatToEndOfStatement();
419 return Error(Loc, "unexpected token");
423 if (getLexer().isNot(AsmToken::EndOfStatement)) {
424 SMLoc Loc = getLexer().getLoc();
425 Parser.eatToEndOfStatement();
426 return Error(Loc, "unexpected token");
428 Parser.Lex(); // Consume the EndOfStatement.
432 bool SparcAsmParser::
433 ParseDirective(AsmToken DirectiveID)
435 // Ignore all directives for now.
436 Parser.eatToEndOfStatement();
440 SparcAsmParser::OperandMatchResultTy SparcAsmParser::
441 parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands)
445 unsigned BaseReg = 0;
447 if (ParseRegister(BaseReg, S, E)) {
448 return MatchOperand_NoMatch;
451 switch (getLexer().getKind()) {
452 default: return MatchOperand_NoMatch;
454 case AsmToken::RBrac:
455 case AsmToken::EndOfStatement:
456 Operands.push_back(SparcOperand::CreateMEMri(BaseReg, 0, S, E));
457 return MatchOperand_Success;
459 case AsmToken:: Plus:
460 Parser.Lex(); // Eat the '+'
462 case AsmToken::Minus:
466 SparcOperand *Offset = 0;
467 OperandMatchResultTy ResTy = parseSparcAsmOperand(Offset);
468 if (ResTy != MatchOperand_Success || !Offset)
469 return MatchOperand_NoMatch;
471 Offset = (Offset->isImm()
472 ? SparcOperand::MorphToMEMri(BaseReg, Offset)
473 : SparcOperand::MorphToMEMrr(BaseReg, Offset));
475 Operands.push_back(Offset);
476 return MatchOperand_Success;
479 SparcAsmParser::OperandMatchResultTy SparcAsmParser::
480 parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
484 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
486 // If there wasn't a custom match, try the generic matcher below. Otherwise,
487 // there was a match, but an error occurred, in which case, just return that
488 // the operand parsing failed.
489 if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail)
492 if (getLexer().is(AsmToken::LBrac)) {
494 Operands.push_back(SparcOperand::CreateToken("[",
495 Parser.getTok().getLoc()));
496 Parser.Lex(); // Eat the [
498 ResTy = parseMEMOperand(Operands);
499 if (ResTy != MatchOperand_Success)
502 if (!getLexer().is(AsmToken::RBrac))
503 return MatchOperand_ParseFail;
505 Operands.push_back(SparcOperand::CreateToken("]",
506 Parser.getTok().getLoc()));
507 Parser.Lex(); // Eat the ]
508 return MatchOperand_Success;
511 SparcOperand *Op = 0;
512 ResTy = parseSparcAsmOperand(Op);
513 if (ResTy != MatchOperand_Success || !Op)
514 return MatchOperand_ParseFail;
516 // Push the parsed operand into the list of operands
517 Operands.push_back(Op);
519 return MatchOperand_Success;
522 SparcAsmParser::OperandMatchResultTy
523 SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op)
526 SMLoc S = Parser.getTok().getLoc();
527 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
531 switch (getLexer().getKind()) {
534 case AsmToken::Percent:
535 Parser.Lex(); // Eat the '%'.
537 if (matchRegisterName(Parser.getTok(), RegNo, false, false)) {
538 Parser.Lex(); // Eat the identifier token.
539 Op = SparcOperand::CreateReg(RegNo, SparcOperand::rk_None, S, E);
542 // FIXME: Handle modifiers like %hi, %lo etc.,
545 case AsmToken::Minus:
546 case AsmToken::Integer:
547 if (!getParser().parseExpression(EVal))
548 Op = SparcOperand::CreateImm(EVal, S, E);
551 case AsmToken::Identifier: {
552 StringRef Identifier;
553 if (!getParser().parseIdentifier(Identifier)) {
554 SMLoc E = SMLoc::getFromPointer(Parser.getTok().
555 getLoc().getPointer() - 1);
556 MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier);
558 const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
561 Op = SparcOperand::CreateImm(Res, S, E);
566 return (Op) ? MatchOperand_Success : MatchOperand_ParseFail;
569 bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
576 if (Tok.is(AsmToken::Identifier)) {
577 StringRef name = Tok.getString();
580 if (name.equals("fp")) {
585 if (name.equals("sp")) {
590 if (name.equals("y")) {
595 if (name.equals("icc")) {
600 if (name.equals("xcc")) {
601 // FIXME:: check 64bit.
607 if (name.substr(0, 3).equals_lower("fcc")
608 && !name.substr(3).getAsInteger(10, intVal)
610 // FIXME: check 64bit and handle %fcc1 - %fcc3
616 if (name.substr(0, 1).equals_lower("g")
617 && !name.substr(1).getAsInteger(10, intVal)
619 RegNo = IntRegs[intVal];
623 if (name.substr(0, 1).equals_lower("o")
624 && !name.substr(1).getAsInteger(10, intVal)
626 RegNo = IntRegs[8 + intVal];
629 if (name.substr(0, 1).equals_lower("l")
630 && !name.substr(1).getAsInteger(10, intVal)
632 RegNo = IntRegs[16 + intVal];
635 if (name.substr(0, 1).equals_lower("i")
636 && !name.substr(1).getAsInteger(10, intVal)
638 RegNo = IntRegs[24 + intVal];
642 if (name.substr(0, 1).equals_lower("f")
643 && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 32) {
644 if (isDFP && (intVal%2 == 0)) {
645 RegNo = DoubleRegs[intVal/2];
646 } else if (isQFP && (intVal%4 == 0)) {
647 RegNo = QuadFPRegs[intVal/4];
649 RegNo = FloatRegs[intVal];
654 if (name.substr(0, 1).equals_lower("f")
655 && !name.substr(1, 2).getAsInteger(10, intVal)
656 && intVal >= 32 && intVal <= 62 && (intVal % 2 == 0)) {
658 RegNo = DoubleRegs[16 + intVal/2];
659 } else if (isQFP && (intVal % 4 == 0)) {
660 RegNo = QuadFPRegs[8 + intVal/4];
668 if (name.substr(0, 1).equals_lower("r")
669 && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) {
670 RegNo = IntRegs[intVal];
679 extern "C" void LLVMInitializeSparcAsmParser() {
680 RegisterMCAsmParser<SparcAsmParser> A(TheSparcTarget);
681 RegisterMCAsmParser<SparcAsmParser> B(TheSparcV9Target);
684 #define GET_REGISTER_MATCHER
685 #define GET_MATCHER_IMPLEMENTATION
686 #include "SparcGenAsmMatcher.inc"