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