Move TargetRegistry and TargetSelect from Target to Support where they belong.
[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/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   default: break;
327   case Match_Success:
328     Out.EmitInstruction(Inst);
329     return false;
330   case Match_MissingFeature:
331     return Error(IDLoc, "instruction use requires an option to be enabled");
332   case Match_MnemonicFail:
333       return Error(IDLoc, "unrecognized instruction mnemonic");
334   case Match_ConversionFail:
335     return Error(IDLoc, "unable to convert operands to instruction");
336   case Match_InvalidOperand:
337     ErrorLoc = IDLoc;
338     if (ErrorInfo != ~0U) {
339       if (ErrorInfo >= Operands.size())
340         return Error(IDLoc, "too few operands for instruction");
341
342       ErrorLoc = ((MBlazeOperand*)Operands[ErrorInfo])->getStartLoc();
343       if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
344     }
345
346     return Error(ErrorLoc, "invalid operand for instruction");
347   }
348
349   llvm_unreachable("Implement any new match types added!");
350   return true;
351 }
352
353 MBlazeOperand *MBlazeAsmParser::
354 ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
355   if (Operands.size() != 4)
356     return 0;
357
358   MBlazeOperand &Base = *(MBlazeOperand*)Operands[2];
359   MBlazeOperand &Offset = *(MBlazeOperand*)Operands[3];
360
361   SMLoc S = Base.getStartLoc();
362   SMLoc O = Offset.getStartLoc();
363   SMLoc E = Offset.getEndLoc();
364
365   if (!Base.isReg()) {
366     Error(S, "base address must be a register");
367     return 0;
368   }
369
370   if (!Offset.isReg() && !Offset.isImm()) {
371     Error(O, "offset must be a register or immediate");
372     return 0;
373   }
374
375   MBlazeOperand *Op;
376   if (Offset.isReg())
377     Op = MBlazeOperand::CreateMem(Base.getReg(), Offset.getReg(), S, E);
378   else
379     Op = MBlazeOperand::CreateMem(Base.getReg(), Offset.getImm(), S, E);
380
381   delete Operands.pop_back_val();
382   delete Operands.pop_back_val();
383   Operands.push_back(Op);
384
385   return Op;
386 }
387
388 bool MBlazeAsmParser::ParseRegister(unsigned &RegNo,
389                                     SMLoc &StartLoc, SMLoc &EndLoc) {
390   return (ParseRegister(RegNo) == 0);
391 }
392
393 MBlazeOperand *MBlazeAsmParser::ParseRegister(unsigned &RegNo) {
394   SMLoc S = Parser.getTok().getLoc();
395   SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
396
397   switch (getLexer().getKind()) {
398   default: return 0;
399   case AsmToken::Identifier:
400     RegNo = MatchRegisterName(getLexer().getTok().getIdentifier());
401     if (RegNo == 0)
402       return 0;
403
404     getLexer().Lex();
405     return MBlazeOperand::CreateReg(RegNo, S, E);
406   }
407 }
408
409 static unsigned MatchFslRegister(StringRef String) {
410   if (!String.startswith("rfsl"))
411     return -1;
412
413   unsigned regNum;
414   if (String.substr(4).getAsInteger(10,regNum))
415     return -1;
416
417   return regNum;
418 }
419
420 MBlazeOperand *MBlazeAsmParser::ParseFsl() {
421   SMLoc S = Parser.getTok().getLoc();
422   SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
423
424   switch (getLexer().getKind()) {
425   default: return 0;
426   case AsmToken::Identifier:
427     unsigned reg = MatchFslRegister(getLexer().getTok().getIdentifier());
428     if (reg >= 16)
429       return 0;
430
431     getLexer().Lex();
432     const MCExpr *EVal = MCConstantExpr::Create(reg,getContext());
433     return MBlazeOperand::CreateFslImm(EVal,S,E);
434   }
435 }
436
437 MBlazeOperand *MBlazeAsmParser::ParseImmediate() {
438   SMLoc S = Parser.getTok().getLoc();
439   SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
440
441   const MCExpr *EVal;
442   switch (getLexer().getKind()) {
443   default: return 0;
444   case AsmToken::LParen:
445   case AsmToken::Plus:
446   case AsmToken::Minus:
447   case AsmToken::Integer:
448   case AsmToken::Identifier:
449     if (getParser().ParseExpression(EVal))
450       return 0;
451
452     return MBlazeOperand::CreateImm(EVal, S, E);
453   }
454 }
455
456 MBlazeOperand *MBlazeAsmParser::
457 ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
458   MBlazeOperand *Op;
459
460   // Attempt to parse the next token as a register name
461   unsigned RegNo;
462   Op = ParseRegister(RegNo);
463
464   // Attempt to parse the next token as an FSL immediate
465   if (!Op)
466     Op = ParseFsl();
467
468   // Attempt to parse the next token as an immediate
469   if (!Op)
470     Op = ParseImmediate();
471
472   // If the token could not be parsed then fail
473   if (!Op) {
474     Error(Parser.getTok().getLoc(), "unknown operand");
475     return 0;
476   }
477
478   // Push the parsed operand into the list of operands
479   Operands.push_back(Op);
480   return Op;
481 }
482
483 /// Parse an mblaze instruction mnemonic followed by its operands.
484 bool MBlazeAsmParser::
485 ParseInstruction(StringRef Name, SMLoc NameLoc,
486                  SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
487   // The first operands is the token for the instruction name
488   size_t dotLoc = Name.find('.');
489   Operands.push_back(MBlazeOperand::CreateToken(Name.substr(0,dotLoc),NameLoc));
490   if (dotLoc < Name.size())
491     Operands.push_back(MBlazeOperand::CreateToken(Name.substr(dotLoc),NameLoc));
492
493   // If there are no more operands then finish
494   if (getLexer().is(AsmToken::EndOfStatement))
495     return false;
496
497   // Parse the first operand
498   if (!ParseOperand(Operands))
499     return true;
500
501   while (getLexer().isNot(AsmToken::EndOfStatement) &&
502          getLexer().is(AsmToken::Comma)) {
503     // Consume the comma token
504     getLexer().Lex();
505
506     // Parse the next operand
507     if (!ParseOperand(Operands))
508       return true;
509   }
510
511   // If the instruction requires a memory operand then we need to
512   // replace the last two operands (base+offset) with a single
513   // memory operand.
514   if (Name.startswith("lw") || Name.startswith("sw") ||
515       Name.startswith("lh") || Name.startswith("sh") ||
516       Name.startswith("lb") || Name.startswith("sb"))
517     return (ParseMemory(Operands) == NULL);
518
519   return false;
520 }
521
522 /// ParseDirective parses the arm specific directives
523 bool MBlazeAsmParser::ParseDirective(AsmToken DirectiveID) {
524   StringRef IDVal = DirectiveID.getIdentifier();
525   if (IDVal == ".word")
526     return ParseDirectiveWord(2, DirectiveID.getLoc());
527   return true;
528 }
529
530 /// ParseDirectiveWord
531 ///  ::= .word [ expression (, expression)* ]
532 bool MBlazeAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
533   if (getLexer().isNot(AsmToken::EndOfStatement)) {
534     for (;;) {
535       const MCExpr *Value;
536       if (getParser().ParseExpression(Value))
537         return true;
538
539       getParser().getStreamer().EmitValue(Value, Size, 0 /*addrspace*/);
540
541       if (getLexer().is(AsmToken::EndOfStatement))
542         break;
543
544       // FIXME: Improve diagnostic.
545       if (getLexer().isNot(AsmToken::Comma))
546         return Error(L, "unexpected token in directive");
547       Parser.Lex();
548     }
549   }
550
551   Parser.Lex();
552   return false;
553 }
554
555 extern "C" void LLVMInitializeMBlazeAsmLexer();
556
557 /// Force static initialization.
558 extern "C" void LLVMInitializeMBlazeAsmParser() {
559   RegisterMCAsmParser<MBlazeAsmParser> X(TheMBlazeTarget);
560   LLVMInitializeMBlazeAsmLexer();
561 }
562
563 #define GET_REGISTER_MATCHER
564 #define GET_MATCHER_IMPLEMENTATION
565 #include "MBlazeGenAsmMatcher.inc"