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