The ConvertToMCInst() function can't fail, so remove the now dead Match_ConversionFai...
[oota-llvm.git] / lib / Target / MBlaze / AsmParser / MBlazeAsmParser.cpp
1 //===-- MBlazeAsmParser.cpp - Parse MBlaze asm to MCInst instructions -----===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "MCTargetDesc/MBlazeBaseInfo.h"
11 #include "llvm/MC/MCParser/MCAsmLexer.h"
12 #include "llvm/MC/MCParser/MCAsmParser.h"
13 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
14 #include "llvm/MC/MCStreamer.h"
15 #include "llvm/MC/MCExpr.h"
16 #include "llvm/MC/MCInst.h"
17 #include "llvm/MC/MCTargetAsmParser.h"
18 #include "llvm/Support/SourceMgr.h"
19 #include "llvm/Support/TargetRegistry.h"
20 #include "llvm/Support/raw_ostream.h"
21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/ADT/Twine.h"
23 using namespace llvm;
24
25 namespace {
26 struct MBlazeOperand;
27
28 class MBlazeAsmParser : public MCTargetAsmParser {
29   MCAsmParser &Parser;
30
31   MCAsmParser &getParser() const { return Parser; }
32   MCAsmLexer &getLexer() const { return Parser.getLexer(); }
33
34   void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
35   bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
36
37   MBlazeOperand *ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
38   MBlazeOperand *ParseRegister(unsigned &RegNo);
39   MBlazeOperand *ParseImmediate();
40   MBlazeOperand *ParseFsl();
41   MBlazeOperand* ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
42
43   virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
44
45   bool ParseDirectiveWord(unsigned Size, SMLoc L);
46
47   bool MatchAndEmitInstruction(SMLoc IDLoc,
48                                SmallVectorImpl<MCParsedAsmOperand*> &Operands,
49                                MCStreamer &Out);
50
51   /// @name Auto-generated Match Functions
52   /// {
53
54 #define GET_ASSEMBLER_HEADER
55 #include "MBlazeGenAsmMatcher.inc"
56
57   /// }
58
59
60 public:
61   MBlazeAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
62     : MCTargetAsmParser(), Parser(_Parser) {}
63
64   virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
65                                 SmallVectorImpl<MCParsedAsmOperand*> &Operands);
66
67   virtual bool ParseDirective(AsmToken DirectiveID);
68 };
69
70 /// MBlazeOperand - Instances of this class represent a parsed MBlaze machine
71 /// instruction.
72 struct MBlazeOperand : public MCParsedAsmOperand {
73   enum KindTy {
74     Token,
75     Immediate,
76     Register,
77     Memory,
78     Fsl
79   } Kind;
80
81   SMLoc StartLoc, EndLoc;
82
83   union {
84     struct {
85       const char *Data;
86       unsigned Length;
87     } Tok;
88
89     struct {
90       unsigned RegNum;
91     } Reg;
92
93     struct {
94       const MCExpr *Val;
95     } Imm;
96
97     struct {
98       unsigned Base;
99       unsigned OffReg;
100       const MCExpr *Off;
101     } Mem;
102
103     struct {
104       const MCExpr *Val;
105     } FslImm;
106   };
107
108   MBlazeOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
109 public:
110   MBlazeOperand(const MBlazeOperand &o) : MCParsedAsmOperand() {
111     Kind = o.Kind;
112     StartLoc = o.StartLoc;
113     EndLoc = o.EndLoc;
114     switch (Kind) {
115     case Register:
116       Reg = o.Reg;
117       break;
118     case Immediate:
119       Imm = o.Imm;
120       break;
121     case Token:
122       Tok = o.Tok;
123       break;
124     case Memory:
125       Mem = o.Mem;
126       break;
127     case Fsl:
128       FslImm = o.FslImm;
129       break;
130     }
131   }
132
133   /// getStartLoc - Get the location of the first token of this operand.
134   SMLoc getStartLoc() const { return StartLoc; }
135
136   /// getEndLoc - Get the location of the last token of this operand.
137   SMLoc getEndLoc() const { return EndLoc; }
138
139   unsigned getReg() const {
140     assert(Kind == Register && "Invalid access!");
141     return Reg.RegNum;
142   }
143
144   const MCExpr *getImm() const {
145     assert(Kind == Immediate && "Invalid access!");
146     return Imm.Val;
147   }
148
149   const MCExpr *getFslImm() const {
150     assert(Kind == Fsl && "Invalid access!");
151     return FslImm.Val;
152   }
153
154   unsigned getMemBase() const {
155     assert(Kind == Memory && "Invalid access!");
156     return Mem.Base;
157   }
158
159   const MCExpr* getMemOff() const {
160     assert(Kind == Memory && "Invalid access!");
161     return Mem.Off;
162   }
163
164   unsigned getMemOffReg() const {
165     assert(Kind == Memory && "Invalid access!");
166     return Mem.OffReg;
167   }
168
169   bool isToken() const { return Kind == Token; }
170   bool isImm() const { return Kind == Immediate; }
171   bool isMem() const { return Kind == Memory; }
172   bool isFsl() const { return Kind == Fsl; }
173   bool isReg() const { return Kind == Register; }
174
175   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
176     // Add as immediates when possible.  Null MCExpr = 0.
177     if (Expr == 0)
178       Inst.addOperand(MCOperand::CreateImm(0));
179     else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
180       Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
181     else
182       Inst.addOperand(MCOperand::CreateExpr(Expr));
183   }
184
185   void addRegOperands(MCInst &Inst, unsigned N) const {
186     assert(N == 1 && "Invalid number of operands!");
187     Inst.addOperand(MCOperand::CreateReg(getReg()));
188   }
189
190   void addImmOperands(MCInst &Inst, unsigned N) const {
191     assert(N == 1 && "Invalid number of operands!");
192     addExpr(Inst, getImm());
193   }
194
195   void addFslOperands(MCInst &Inst, unsigned N) const {
196     assert(N == 1 && "Invalid number of operands!");
197     addExpr(Inst, getFslImm());
198   }
199
200   void addMemOperands(MCInst &Inst, unsigned N) const {
201     assert(N == 2 && "Invalid number of operands!");
202
203     Inst.addOperand(MCOperand::CreateReg(getMemBase()));
204
205     unsigned RegOff = getMemOffReg();
206     if (RegOff)
207       Inst.addOperand(MCOperand::CreateReg(RegOff));
208     else
209       addExpr(Inst, getMemOff());
210   }
211
212   StringRef getToken() const {
213     assert(Kind == Token && "Invalid access!");
214     return StringRef(Tok.Data, Tok.Length);
215   }
216
217   virtual void print(raw_ostream &OS) const;
218
219   static MBlazeOperand *CreateToken(StringRef Str, SMLoc S) {
220     MBlazeOperand *Op = new MBlazeOperand(Token);
221     Op->Tok.Data = Str.data();
222     Op->Tok.Length = Str.size();
223     Op->StartLoc = S;
224     Op->EndLoc = S;
225     return Op;
226   }
227
228   static MBlazeOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
229     MBlazeOperand *Op = new MBlazeOperand(Register);
230     Op->Reg.RegNum = RegNum;
231     Op->StartLoc = S;
232     Op->EndLoc = E;
233     return Op;
234   }
235
236   static MBlazeOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
237     MBlazeOperand *Op = new MBlazeOperand(Immediate);
238     Op->Imm.Val = Val;
239     Op->StartLoc = S;
240     Op->EndLoc = E;
241     return Op;
242   }
243
244   static MBlazeOperand *CreateFslImm(const MCExpr *Val, SMLoc S, SMLoc E) {
245     MBlazeOperand *Op = new MBlazeOperand(Fsl);
246     Op->Imm.Val = Val;
247     Op->StartLoc = S;
248     Op->EndLoc = E;
249     return Op;
250   }
251
252   static MBlazeOperand *CreateMem(unsigned Base, const MCExpr *Off, SMLoc S,
253                                   SMLoc E) {
254     MBlazeOperand *Op = new MBlazeOperand(Memory);
255     Op->Mem.Base = Base;
256     Op->Mem.Off = Off;
257     Op->Mem.OffReg = 0;
258     Op->StartLoc = S;
259     Op->EndLoc = E;
260     return Op;
261   }
262
263   static MBlazeOperand *CreateMem(unsigned Base, unsigned Off, SMLoc S,
264                                   SMLoc E) {
265     MBlazeOperand *Op = new MBlazeOperand(Memory);
266     Op->Mem.Base = Base;
267     Op->Mem.OffReg = Off;
268     Op->Mem.Off = 0;
269     Op->StartLoc = S;
270     Op->EndLoc = E;
271     return Op;
272   }
273 };
274
275 } // end anonymous namespace.
276
277 void MBlazeOperand::print(raw_ostream &OS) const {
278   switch (Kind) {
279   case Immediate:
280     getImm()->print(OS);
281     break;
282   case Register:
283     OS << "<register R";
284     OS << getMBlazeRegisterNumbering(getReg()) << ">";
285     break;
286   case Token:
287     OS << "'" << getToken() << "'";
288     break;
289   case Memory: {
290     OS << "<memory R";
291     OS << getMBlazeRegisterNumbering(getMemBase());
292     OS << ", ";
293
294     unsigned RegOff = getMemOffReg();
295     if (RegOff)
296       OS << "R" << getMBlazeRegisterNumbering(RegOff);
297     else
298       OS << getMemOff();
299     OS << ">";
300     }
301     break;
302   case Fsl:
303     getFslImm()->print(OS);
304     break;
305   }
306 }
307
308 /// @name Auto-generated Match Functions
309 /// {
310
311 static unsigned MatchRegisterName(StringRef Name);
312
313 /// }
314 //
315 bool MBlazeAsmParser::
316 MatchAndEmitInstruction(SMLoc IDLoc,
317                         SmallVectorImpl<MCParsedAsmOperand*> &Operands,
318                         MCStreamer &Out) {
319   MCInst Inst;
320   SMLoc ErrorLoc;
321   unsigned ErrorInfo;
322
323   switch (MatchInstructionImpl(Operands, Inst, ErrorInfo)) {
324   default: break;
325   case Match_Success:
326     Out.EmitInstruction(Inst);
327     return false;
328   case Match_MissingFeature:
329     return Error(IDLoc, "instruction use requires an option to be enabled");
330   case Match_MnemonicFail:
331       return Error(IDLoc, "unrecognized instruction mnemonic");
332   case Match_InvalidOperand:
333     ErrorLoc = IDLoc;
334     if (ErrorInfo != ~0U) {
335       if (ErrorInfo >= Operands.size())
336         return Error(IDLoc, "too few operands for instruction");
337
338       ErrorLoc = ((MBlazeOperand*)Operands[ErrorInfo])->getStartLoc();
339       if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
340     }
341
342     return Error(ErrorLoc, "invalid operand for instruction");
343   }
344
345   llvm_unreachable("Implement any new match types added!");
346 }
347
348 MBlazeOperand *MBlazeAsmParser::
349 ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
350   if (Operands.size() != 4)
351     return 0;
352
353   MBlazeOperand &Base = *(MBlazeOperand*)Operands[2];
354   MBlazeOperand &Offset = *(MBlazeOperand*)Operands[3];
355
356   SMLoc S = Base.getStartLoc();
357   SMLoc O = Offset.getStartLoc();
358   SMLoc E = Offset.getEndLoc();
359
360   if (!Base.isReg()) {
361     Error(S, "base address must be a register");
362     return 0;
363   }
364
365   if (!Offset.isReg() && !Offset.isImm()) {
366     Error(O, "offset must be a register or immediate");
367     return 0;
368   }
369
370   MBlazeOperand *Op;
371   if (Offset.isReg())
372     Op = MBlazeOperand::CreateMem(Base.getReg(), Offset.getReg(), S, E);
373   else
374     Op = MBlazeOperand::CreateMem(Base.getReg(), Offset.getImm(), S, E);
375
376   delete Operands.pop_back_val();
377   delete Operands.pop_back_val();
378   Operands.push_back(Op);
379
380   return Op;
381 }
382
383 bool MBlazeAsmParser::ParseRegister(unsigned &RegNo,
384                                     SMLoc &StartLoc, SMLoc &EndLoc) {
385   return (ParseRegister(RegNo) == 0);
386 }
387
388 MBlazeOperand *MBlazeAsmParser::ParseRegister(unsigned &RegNo) {
389   SMLoc S = Parser.getTok().getLoc();
390   SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
391
392   switch (getLexer().getKind()) {
393   default: return 0;
394   case AsmToken::Identifier:
395     RegNo = MatchRegisterName(getLexer().getTok().getIdentifier());
396     if (RegNo == 0)
397       return 0;
398
399     getLexer().Lex();
400     return MBlazeOperand::CreateReg(RegNo, S, E);
401   }
402 }
403
404 static unsigned MatchFslRegister(StringRef String) {
405   if (!String.startswith("rfsl"))
406     return -1;
407
408   unsigned regNum;
409   if (String.substr(4).getAsInteger(10,regNum))
410     return -1;
411
412   return regNum;
413 }
414
415 MBlazeOperand *MBlazeAsmParser::ParseFsl() {
416   SMLoc S = Parser.getTok().getLoc();
417   SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
418
419   switch (getLexer().getKind()) {
420   default: return 0;
421   case AsmToken::Identifier:
422     unsigned reg = MatchFslRegister(getLexer().getTok().getIdentifier());
423     if (reg >= 16)
424       return 0;
425
426     getLexer().Lex();
427     const MCExpr *EVal = MCConstantExpr::Create(reg,getContext());
428     return MBlazeOperand::CreateFslImm(EVal,S,E);
429   }
430 }
431
432 MBlazeOperand *MBlazeAsmParser::ParseImmediate() {
433   SMLoc S = Parser.getTok().getLoc();
434   SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
435
436   const MCExpr *EVal;
437   switch (getLexer().getKind()) {
438   default: return 0;
439   case AsmToken::LParen:
440   case AsmToken::Plus:
441   case AsmToken::Minus:
442   case AsmToken::Integer:
443   case AsmToken::Identifier:
444     if (getParser().ParseExpression(EVal))
445       return 0;
446
447     return MBlazeOperand::CreateImm(EVal, S, E);
448   }
449 }
450
451 MBlazeOperand *MBlazeAsmParser::
452 ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
453   MBlazeOperand *Op;
454
455   // Attempt to parse the next token as a register name
456   unsigned RegNo;
457   Op = ParseRegister(RegNo);
458
459   // Attempt to parse the next token as an FSL immediate
460   if (!Op)
461     Op = ParseFsl();
462
463   // Attempt to parse the next token as an immediate
464   if (!Op)
465     Op = ParseImmediate();
466
467   // If the token could not be parsed then fail
468   if (!Op) {
469     Error(Parser.getTok().getLoc(), "unknown operand");
470     return 0;
471   }
472
473   // Push the parsed operand into the list of operands
474   Operands.push_back(Op);
475   return Op;
476 }
477
478 /// Parse an mblaze instruction mnemonic followed by its operands.
479 bool MBlazeAsmParser::
480 ParseInstruction(StringRef Name, SMLoc NameLoc,
481                  SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
482   // The first operands is the token for the instruction name
483   size_t dotLoc = Name.find('.');
484   Operands.push_back(MBlazeOperand::CreateToken(Name.substr(0,dotLoc),NameLoc));
485   if (dotLoc < Name.size())
486     Operands.push_back(MBlazeOperand::CreateToken(Name.substr(dotLoc),NameLoc));
487
488   // If there are no more operands then finish
489   if (getLexer().is(AsmToken::EndOfStatement))
490     return false;
491
492   // Parse the first operand
493   if (!ParseOperand(Operands))
494     return true;
495
496   while (getLexer().isNot(AsmToken::EndOfStatement) &&
497          getLexer().is(AsmToken::Comma)) {
498     // Consume the comma token
499     getLexer().Lex();
500
501     // Parse the next operand
502     if (!ParseOperand(Operands))
503       return true;
504   }
505
506   // If the instruction requires a memory operand then we need to
507   // replace the last two operands (base+offset) with a single
508   // memory operand.
509   if (Name.startswith("lw") || Name.startswith("sw") ||
510       Name.startswith("lh") || Name.startswith("sh") ||
511       Name.startswith("lb") || Name.startswith("sb"))
512     return (ParseMemory(Operands) == NULL);
513
514   return false;
515 }
516
517 /// ParseDirective parses the MBlaze specific directives
518 bool MBlazeAsmParser::ParseDirective(AsmToken DirectiveID) {
519   StringRef IDVal = DirectiveID.getIdentifier();
520   if (IDVal == ".word")
521     return ParseDirectiveWord(2, DirectiveID.getLoc());
522   return true;
523 }
524
525 /// ParseDirectiveWord
526 ///  ::= .word [ expression (, expression)* ]
527 bool MBlazeAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
528   if (getLexer().isNot(AsmToken::EndOfStatement)) {
529     for (;;) {
530       const MCExpr *Value;
531       if (getParser().ParseExpression(Value))
532         return true;
533
534       getParser().getStreamer().EmitValue(Value, Size, 0 /*addrspace*/);
535
536       if (getLexer().is(AsmToken::EndOfStatement))
537         break;
538
539       // FIXME: Improve diagnostic.
540       if (getLexer().isNot(AsmToken::Comma))
541         return Error(L, "unexpected token in directive");
542       Parser.Lex();
543     }
544   }
545
546   Parser.Lex();
547   return false;
548 }
549
550 extern "C" void LLVMInitializeMBlazeAsmLexer();
551
552 /// Force static initialization.
553 extern "C" void LLVMInitializeMBlazeAsmParser() {
554   RegisterMCAsmParser<MBlazeAsmParser> X(TheMBlazeTarget);
555   LLVMInitializeMBlazeAsmLexer();
556 }
557
558 #define GET_REGISTER_MATCHER
559 #define GET_MATCHER_IMPLEMENTATION
560 #include "MBlazeGenAsmMatcher.inc"