10a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck//===-- MBlazeAsmParser.cpp - Parse MBlaze asm to MCInst instructions -----===//
24da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck//
34da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck//                     The LLVM Compiler Infrastructure
44da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck//
54da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck// This file is distributed under the University of Illinois Open Source
64da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck// License. See LICENSE.TXT for details.
74da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck//
84da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck//===----------------------------------------------------------------------===//
94da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
1094b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "MCTargetDesc/MBlazeBaseInfo.h"
11d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/SmallVector.h"
12d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/Twine.h"
13d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCExpr.h"
14d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCInst.h"
154da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck#include "llvm/MC/MCParser/MCAsmLexer.h"
164da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck#include "llvm/MC/MCParser/MCAsmParser.h"
174da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
184da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck#include "llvm/MC/MCStreamer.h"
1994b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCTargetAsmParser.h"
204da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck#include "llvm/Support/SourceMgr.h"
213e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h"
224da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck#include "llvm/Support/raw_ostream.h"
234da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peckusing namespace llvm;
244da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
254da992aebada7445ef68a7b6b94676dd26e9d537Wesley Pecknamespace {
264da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peckstruct MBlazeOperand;
274da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
2894b9550a32d189704a8eae55505edf62662c0534Evan Chengclass MBlazeAsmParser : public MCTargetAsmParser {
294da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  MCAsmParser &Parser;
304da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
314da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  MCAsmParser &getParser() const { return Parser; }
324da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
334da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
344da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
354da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
364da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
370a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  MBlazeOperand *ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
383ebe59c892051375623fea55e977ff559fdb3323Jordan Rose  MBlazeOperand *ParseRegister();
393ebe59c892051375623fea55e977ff559fdb3323Jordan Rose  MBlazeOperand *ParseRegister(SMLoc &StartLoc, SMLoc &EndLoc);
400a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  MBlazeOperand *ParseImmediate();
410a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  MBlazeOperand *ParseFsl();
420a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  MBlazeOperand* ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
434da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
44bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
45bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
4641400da31ead2f61d171381c0945dceddd8fc786Wesley Peck  bool ParseDirectiveWord(unsigned Size, SMLoc L);
4741400da31ead2f61d171381c0945dceddd8fc786Wesley Peck
4884125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
494da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
5084125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier                               MCStreamer &Out, unsigned &ErrorInfo,
5184125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier                               bool MatchingInlineAsm);
524da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
534da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  /// @name Auto-generated Match Functions
544da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  /// {
554da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
564da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck#define GET_ASSEMBLER_HEADER
574da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck#include "MBlazeGenAsmMatcher.inc"
584da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
594da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  /// }
604da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
614da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peckpublic:
62ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  MBlazeAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
6394b9550a32d189704a8eae55505edf62662c0534Evan Cheng    : MCTargetAsmParser(), Parser(_Parser) {}
644da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
656a020a71173a3ea7738a9df69982e85ddbfe0303Chad Rosier  virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
666a020a71173a3ea7738a9df69982e85ddbfe0303Chad Rosier                                SMLoc NameLoc,
674da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck                                SmallVectorImpl<MCParsedAsmOperand*> &Operands);
684da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
694da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  virtual bool ParseDirective(AsmToken DirectiveID);
704da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck};
710a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck
724da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck/// MBlazeOperand - Instances of this class represent a parsed MBlaze machine
734da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck/// instruction.
744da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peckstruct MBlazeOperand : public MCParsedAsmOperand {
754da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  enum KindTy {
760a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    Token,
774da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    Immediate,
784da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    Register,
790a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    Memory,
800a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    Fsl
814da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  } Kind;
824da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
834da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  SMLoc StartLoc, EndLoc;
844da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
85a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct TokOp {
86a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    const char *Data;
87a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    unsigned Length;
88a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
89a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
90a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct RegOp {
91a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    unsigned RegNum;
92a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
93a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
94a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct ImmOp {
95a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    const MCExpr *Val;
96a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
97a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
98a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct MemOp {
99a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    unsigned Base;
100a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    unsigned OffReg;
101a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    const MCExpr *Off;
102a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
103a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
104a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct FslImmOp {
105a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    const MCExpr *Val;
106a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
107a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
1084da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  union {
109a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct TokOp Tok;
110a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct RegOp Reg;
111a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct ImmOp Imm;
112a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct MemOp Mem;
113a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct FslImmOp FslImm;
1144da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  };
1150a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck
1160a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  MBlazeOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
1170a67d92938d77b6a8cde6e1676750264b274cebcWesley Peckpublic:
1184da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  MBlazeOperand(const MBlazeOperand &o) : MCParsedAsmOperand() {
1194da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    Kind = o.Kind;
1204da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    StartLoc = o.StartLoc;
1214da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    EndLoc = o.EndLoc;
1224da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    switch (Kind) {
1234da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    case Register:
1244da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck      Reg = o.Reg;
1254da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck      break;
1264da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    case Immediate:
1274da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck      Imm = o.Imm;
1284da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck      break;
1290a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    case Token:
1300a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck      Tok = o.Tok;
1310a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck      break;
1324da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    case Memory:
1334da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck      Mem = o.Mem;
1344da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck      break;
1350a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    case Fsl:
1360a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck      FslImm = o.FslImm;
1370a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck      break;
1384da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    }
1394da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  }
1400a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck
1414da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  /// getStartLoc - Get the location of the first token of this operand.
1424da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  SMLoc getStartLoc() const { return StartLoc; }
1430a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck
1444da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  /// getEndLoc - Get the location of the last token of this operand.
1454da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  SMLoc getEndLoc() const { return EndLoc; }
1464da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
1474da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  unsigned getReg() const {
1484da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    assert(Kind == Register && "Invalid access!");
1494da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    return Reg.RegNum;
1504da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  }
1514da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
1524da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  const MCExpr *getImm() const {
1534da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    assert(Kind == Immediate && "Invalid access!");
1544da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    return Imm.Val;
1554da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  }
1564da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
1570a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  const MCExpr *getFslImm() const {
1580a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    assert(Kind == Fsl && "Invalid access!");
1590a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    return FslImm.Val;
1600a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  }
1614da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
1620a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  unsigned getMemBase() const {
1630a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    assert(Kind == Memory && "Invalid access!");
1640a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    return Mem.Base;
1650a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  }
1664da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
1670a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  const MCExpr* getMemOff() const {
1680a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    assert(Kind == Memory && "Invalid access!");
1690a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    return Mem.Off;
1700a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  }
1710a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck
1720a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  unsigned getMemOffReg() const {
1730a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    assert(Kind == Memory && "Invalid access!");
1740a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    return Mem.OffReg;
1750a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  }
1764da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
1770a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  bool isToken() const { return Kind == Token; }
1780a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  bool isImm() const { return Kind == Immediate; }
1790a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  bool isMem() const { return Kind == Memory; }
1800a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  bool isFsl() const { return Kind == Fsl; }
1810a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  bool isReg() const { return Kind == Register; }
1824da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
1834da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
1840a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    // Add as immediates when possible.  Null MCExpr = 0.
1850a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    if (Expr == 0)
1860a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck      Inst.addOperand(MCOperand::CreateImm(0));
1870a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1884da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
1894da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    else
1904da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck      Inst.addOperand(MCOperand::CreateExpr(Expr));
1914da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  }
1924da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
1934da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  void addRegOperands(MCInst &Inst, unsigned N) const {
1944da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    assert(N == 1 && "Invalid number of operands!");
1954da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    Inst.addOperand(MCOperand::CreateReg(getReg()));
1964da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  }
1974da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
1984da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  void addImmOperands(MCInst &Inst, unsigned N) const {
1994da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    assert(N == 1 && "Invalid number of operands!");
2004da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    addExpr(Inst, getImm());
2014da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  }
2024da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
2030a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  void addFslOperands(MCInst &Inst, unsigned N) const {
2040a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    assert(N == 1 && "Invalid number of operands!");
2050a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    addExpr(Inst, getFslImm());
2060a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  }
2074da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
2080a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  void addMemOperands(MCInst &Inst, unsigned N) const {
2090a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    assert(N == 2 && "Invalid number of operands!");
2100a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck
21141400da31ead2f61d171381c0945dceddd8fc786Wesley Peck    Inst.addOperand(MCOperand::CreateReg(getMemBase()));
21241400da31ead2f61d171381c0945dceddd8fc786Wesley Peck
2130a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    unsigned RegOff = getMemOffReg();
2140a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    if (RegOff)
2150a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck      Inst.addOperand(MCOperand::CreateReg(RegOff));
2160a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    else
2170a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck      addExpr(Inst, getMemOff());
2180a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  }
2190a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck
2200a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  StringRef getToken() const {
2210a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    assert(Kind == Token && "Invalid access!");
2220a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    return StringRef(Tok.Data, Tok.Length);
2234da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  }
2244da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
225b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach  virtual void print(raw_ostream &OS) const;
2260a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck
2270a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  static MBlazeOperand *CreateToken(StringRef Str, SMLoc S) {
2280a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    MBlazeOperand *Op = new MBlazeOperand(Token);
2294da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    Op->Tok.Data = Str.data();
2304da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    Op->Tok.Length = Str.size();
2314da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    Op->StartLoc = S;
2324da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    Op->EndLoc = S;
2330a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    return Op;
2344da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  }
2354da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
2360a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  static MBlazeOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
2370a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    MBlazeOperand *Op = new MBlazeOperand(Register);
2384da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    Op->Reg.RegNum = RegNum;
2394da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    Op->StartLoc = S;
2404da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    Op->EndLoc = E;
2410a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    return Op;
2420a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  }
2430a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck
2440a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  static MBlazeOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
2450a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    MBlazeOperand *Op = new MBlazeOperand(Immediate);
2460a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    Op->Imm.Val = Val;
2470a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    Op->StartLoc = S;
2480a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    Op->EndLoc = E;
2490a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    return Op;
2504da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  }
2514da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
2520a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  static MBlazeOperand *CreateFslImm(const MCExpr *Val, SMLoc S, SMLoc E) {
2530a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    MBlazeOperand *Op = new MBlazeOperand(Fsl);
2544da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    Op->Imm.Val = Val;
2554da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    Op->StartLoc = S;
2564da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    Op->EndLoc = E;
2570a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    return Op;
2580a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  }
2590a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck
2600a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  static MBlazeOperand *CreateMem(unsigned Base, const MCExpr *Off, SMLoc S,
2610a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck                                  SMLoc E) {
2620a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    MBlazeOperand *Op = new MBlazeOperand(Memory);
2630a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    Op->Mem.Base = Base;
2640a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    Op->Mem.Off = Off;
2650a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    Op->Mem.OffReg = 0;
2660a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    Op->StartLoc = S;
2670a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    Op->EndLoc = E;
2680a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    return Op;
2694da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  }
2704da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
2710a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  static MBlazeOperand *CreateMem(unsigned Base, unsigned Off, SMLoc S,
2720a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck                                  SMLoc E) {
2730a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    MBlazeOperand *Op = new MBlazeOperand(Memory);
2740a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    Op->Mem.Base = Base;
2750a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    Op->Mem.OffReg = Off;
2760a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    Op->Mem.Off = 0;
2774da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    Op->StartLoc = S;
2784da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    Op->EndLoc = E;
2790a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    return Op;
2804da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  }
2814da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck};
2824da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
2834da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck} // end anonymous namespace.
2844da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
285b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid MBlazeOperand::print(raw_ostream &OS) const {
2864da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  switch (Kind) {
2874da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  case Immediate:
2884da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    getImm()->print(OS);
2894da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    break;
2904da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  case Register:
29141400da31ead2f61d171381c0945dceddd8fc786Wesley Peck    OS << "<register R";
2928cb2d61bce5950df8e3b8dec481b88fb2eaa66d0Evan Cheng    OS << getMBlazeRegisterNumbering(getReg()) << ">";
2934da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    break;
2944da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  case Token:
2954da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    OS << "'" << getToken() << "'";
2964da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    break;
29741400da31ead2f61d171381c0945dceddd8fc786Wesley Peck  case Memory: {
29841400da31ead2f61d171381c0945dceddd8fc786Wesley Peck    OS << "<memory R";
2998cb2d61bce5950df8e3b8dec481b88fb2eaa66d0Evan Cheng    OS << getMBlazeRegisterNumbering(getMemBase());
30041400da31ead2f61d171381c0945dceddd8fc786Wesley Peck    OS << ", ";
30141400da31ead2f61d171381c0945dceddd8fc786Wesley Peck
30241400da31ead2f61d171381c0945dceddd8fc786Wesley Peck    unsigned RegOff = getMemOffReg();
30341400da31ead2f61d171381c0945dceddd8fc786Wesley Peck    if (RegOff)
3048cb2d61bce5950df8e3b8dec481b88fb2eaa66d0Evan Cheng      OS << "R" << getMBlazeRegisterNumbering(RegOff);
30541400da31ead2f61d171381c0945dceddd8fc786Wesley Peck    else
30641400da31ead2f61d171381c0945dceddd8fc786Wesley Peck      OS << getMemOff();
30741400da31ead2f61d171381c0945dceddd8fc786Wesley Peck    OS << ">";
30841400da31ead2f61d171381c0945dceddd8fc786Wesley Peck    }
3090a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    break;
3100a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  case Fsl:
3110a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    getFslImm()->print(OS);
3120a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    break;
3134da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  }
3144da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck}
3154da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
3164da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck/// @name Auto-generated Match Functions
3174da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck/// {
3184da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
3194da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peckstatic unsigned MatchRegisterName(StringRef Name);
3204da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
3214da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck/// }
3220a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck//
3230a67d92938d77b6a8cde6e1676750264b274cebcWesley Peckbool MBlazeAsmParser::
32484125ca43c758fd21fdab2b05196e0df57c55c96Chad RosierMatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3250a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
32684125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier                        MCStreamer &Out, unsigned &ErrorInfo,
32784125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier                        bool MatchingInlineAsm) {
3280a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  MCInst Inst;
3296e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier  switch (MatchInstructionImpl(Operands, Inst, ErrorInfo,
330655fa1225b49dc3d8c2f1eed049eaf47ceb3ae8dChad Rosier                               MatchingInlineAsm)) {
33119cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  default: break;
3320a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  case Match_Success:
3330a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    Out.EmitInstruction(Inst);
3340a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    return false;
3350a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  case Match_MissingFeature:
3360a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    return Error(IDLoc, "instruction use requires an option to be enabled");
3370a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  case Match_MnemonicFail:
3380a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck      return Error(IDLoc, "unrecognized instruction mnemonic");
339f2210eda2e37b08b3835a6c2d79929319ae1f603Chad Rosier  case Match_InvalidOperand: {
34061290e3845a9cae85f26468e4367a598c0f3f6c1Chad Rosier    SMLoc ErrorLoc = IDLoc;
3410a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    if (ErrorInfo != ~0U) {
3420a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck      if (ErrorInfo >= Operands.size())
3430a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck        return Error(IDLoc, "too few operands for instruction");
3440a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck
3450a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck      ErrorLoc = ((MBlazeOperand*)Operands[ErrorInfo])->getStartLoc();
3460a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
3474da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck    }
3484da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
3490a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    return Error(ErrorLoc, "invalid operand for instruction");
3500a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  }
351f2210eda2e37b08b3835a6c2d79929319ae1f603Chad Rosier  }
3524da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
3530a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  llvm_unreachable("Implement any new match types added!");
3544da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck}
3554da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
3560a67d92938d77b6a8cde6e1676750264b274cebcWesley PeckMBlazeOperand *MBlazeAsmParser::
3570a67d92938d77b6a8cde6e1676750264b274cebcWesley PeckParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3580a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  if (Operands.size() != 4)
3590a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    return 0;
3604da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
3610a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  MBlazeOperand &Base = *(MBlazeOperand*)Operands[2];
3620a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  MBlazeOperand &Offset = *(MBlazeOperand*)Operands[3];
3634da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
3640a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  SMLoc S = Base.getStartLoc();
3650a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  SMLoc O = Offset.getStartLoc();
3660a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  SMLoc E = Offset.getEndLoc();
3670a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck
3680a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  if (!Base.isReg()) {
3690a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    Error(S, "base address must be a register");
3700a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    return 0;
3714da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  }
3724da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
3730a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  if (!Offset.isReg() && !Offset.isImm()) {
3740a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    Error(O, "offset must be a register or immediate");
3750a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    return 0;
3764da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  }
3774da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
3780a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  MBlazeOperand *Op;
3790a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  if (Offset.isReg())
3800a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    Op = MBlazeOperand::CreateMem(Base.getReg(), Offset.getReg(), S, E);
3810a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  else
3820a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    Op = MBlazeOperand::CreateMem(Base.getReg(), Offset.getImm(), S, E);
3830a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck
3840a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  delete Operands.pop_back_val();
3850a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  delete Operands.pop_back_val();
3860a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  Operands.push_back(Op);
3870a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck
3880a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  return Op;
3894da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck}
3904da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
39169df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool MBlazeAsmParser::ParseRegister(unsigned &RegNo,
39269df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson                                    SMLoc &StartLoc, SMLoc &EndLoc) {
3933ebe59c892051375623fea55e977ff559fdb3323Jordan Rose  MBlazeOperand *Reg = ParseRegister(StartLoc, EndLoc);
3943ebe59c892051375623fea55e977ff559fdb3323Jordan Rose  if (!Reg)
3953ebe59c892051375623fea55e977ff559fdb3323Jordan Rose    return true;
3963ebe59c892051375623fea55e977ff559fdb3323Jordan Rose  RegNo = Reg->getReg();
3973ebe59c892051375623fea55e977ff559fdb3323Jordan Rose  return false;
398bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky}
399bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
4003ebe59c892051375623fea55e977ff559fdb3323Jordan RoseMBlazeOperand *MBlazeAsmParser::ParseRegister() {
4013ebe59c892051375623fea55e977ff559fdb3323Jordan Rose  SMLoc S, E;
4023ebe59c892051375623fea55e977ff559fdb3323Jordan Rose  return ParseRegister(S, E);
4033ebe59c892051375623fea55e977ff559fdb3323Jordan Rose}
4040a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck
4053ebe59c892051375623fea55e977ff559fdb3323Jordan RoseMBlazeOperand *MBlazeAsmParser::ParseRegister(SMLoc &StartLoc, SMLoc &EndLoc) {
4063ebe59c892051375623fea55e977ff559fdb3323Jordan Rose  StartLoc = Parser.getTok().getLoc();
4073ebe59c892051375623fea55e977ff559fdb3323Jordan Rose  EndLoc = Parser.getTok().getEndLoc();
4080a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck
4093ebe59c892051375623fea55e977ff559fdb3323Jordan Rose  if (getLexer().getKind() != AsmToken::Identifier)
4103ebe59c892051375623fea55e977ff559fdb3323Jordan Rose    return 0;
4113ebe59c892051375623fea55e977ff559fdb3323Jordan Rose
4123ebe59c892051375623fea55e977ff559fdb3323Jordan Rose  unsigned RegNo = MatchRegisterName(getLexer().getTok().getIdentifier());
4133ebe59c892051375623fea55e977ff559fdb3323Jordan Rose  if (RegNo == 0)
4143ebe59c892051375623fea55e977ff559fdb3323Jordan Rose    return 0;
4153ebe59c892051375623fea55e977ff559fdb3323Jordan Rose
4163ebe59c892051375623fea55e977ff559fdb3323Jordan Rose  getLexer().Lex();
4173ebe59c892051375623fea55e977ff559fdb3323Jordan Rose  return MBlazeOperand::CreateReg(RegNo, StartLoc, EndLoc);
4184da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck}
4194da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
420d53f3c864bf94d158a2ae677fe92fd41afaec2f3Benjamin Kramerstatic unsigned MatchFslRegister(StringRef String) {
4210a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  if (!String.startswith("rfsl"))
4220a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    return -1;
4234da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
4240a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  unsigned regNum;
4250a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  if (String.substr(4).getAsInteger(10,regNum))
4260a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    return -1;
4274da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
4280a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  return regNum;
4290a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck}
4304da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
4310a67d92938d77b6a8cde6e1676750264b274cebcWesley PeckMBlazeOperand *MBlazeAsmParser::ParseFsl() {
4320a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  SMLoc S = Parser.getTok().getLoc();
4333ebe59c892051375623fea55e977ff559fdb3323Jordan Rose  SMLoc E = Parser.getTok().getEndLoc();
4344da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
4350a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  switch (getLexer().getKind()) {
4360a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  default: return 0;
4370a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  case AsmToken::Identifier:
4380a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    unsigned reg = MatchFslRegister(getLexer().getTok().getIdentifier());
4390a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    if (reg >= 16)
4400a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck      return 0;
4410a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck
44241400da31ead2f61d171381c0945dceddd8fc786Wesley Peck    getLexer().Lex();
4430a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    const MCExpr *EVal = MCConstantExpr::Create(reg,getContext());
4440a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    return MBlazeOperand::CreateFslImm(EVal,S,E);
4450a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  }
4464da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck}
4474da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
4480a67d92938d77b6a8cde6e1676750264b274cebcWesley PeckMBlazeOperand *MBlazeAsmParser::ParseImmediate() {
4490a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  SMLoc S = Parser.getTok().getLoc();
4503ebe59c892051375623fea55e977ff559fdb3323Jordan Rose  SMLoc E = Parser.getTok().getEndLoc();
4510a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck
4520a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  const MCExpr *EVal;
4534da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  switch (getLexer().getKind()) {
4540a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  default: return 0;
4550a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  case AsmToken::LParen:
4560a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  case AsmToken::Plus:
4570a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  case AsmToken::Minus:
4580a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  case AsmToken::Integer:
4594da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  case AsmToken::Identifier:
460cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    if (getParser().parseExpression(EVal))
4610a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck      return 0;
4620a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck
4630a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    return MBlazeOperand::CreateImm(EVal, S, E);
4644da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  }
4654da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck}
4664da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
4670a67d92938d77b6a8cde6e1676750264b274cebcWesley PeckMBlazeOperand *MBlazeAsmParser::
4680a67d92938d77b6a8cde6e1676750264b274cebcWesley PeckParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
4690a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  MBlazeOperand *Op;
4704da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
4710a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  // Attempt to parse the next token as a register name
4723ebe59c892051375623fea55e977ff559fdb3323Jordan Rose  Op = ParseRegister();
4734da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
4740a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  // Attempt to parse the next token as an FSL immediate
4750a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  if (!Op)
4760a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    Op = ParseFsl();
4774da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
4780a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  // Attempt to parse the next token as an immediate
4790a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  if (!Op)
4800a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    Op = ParseImmediate();
4814da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
4820a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  // If the token could not be parsed then fail
4830a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  if (!Op) {
4840a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    Error(Parser.getTok().getLoc(), "unknown operand");
4850a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    return 0;
4864da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  }
4874da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
4880a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  // Push the parsed operand into the list of operands
4890a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  Operands.push_back(Op);
4900a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  return Op;
4914da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck}
4924da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
4930a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck/// Parse an mblaze instruction mnemonic followed by its operands.
4940a67d92938d77b6a8cde6e1676750264b274cebcWesley Peckbool MBlazeAsmParser::
4956a020a71173a3ea7738a9df69982e85ddbfe0303Chad RosierParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
4960a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck                 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
49741400da31ead2f61d171381c0945dceddd8fc786Wesley Peck  // The first operands is the token for the instruction name
49841400da31ead2f61d171381c0945dceddd8fc786Wesley Peck  size_t dotLoc = Name.find('.');
49941400da31ead2f61d171381c0945dceddd8fc786Wesley Peck  Operands.push_back(MBlazeOperand::CreateToken(Name.substr(0,dotLoc),NameLoc));
50041400da31ead2f61d171381c0945dceddd8fc786Wesley Peck  if (dotLoc < Name.size())
50141400da31ead2f61d171381c0945dceddd8fc786Wesley Peck    Operands.push_back(MBlazeOperand::CreateToken(Name.substr(dotLoc),NameLoc));
5020a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck
5030a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  // If there are no more operands then finish
5040a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  if (getLexer().is(AsmToken::EndOfStatement))
5050a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    return false;
5064da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
5070a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  // Parse the first operand
50860f923c5e2d752ce5c6e042db8279122eff798ddWesley Peck  if (!ParseOperand(Operands))
5090a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    return true;
5104da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
5110a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  while (getLexer().isNot(AsmToken::EndOfStatement) &&
5120a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck         getLexer().is(AsmToken::Comma)) {
5130a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    // Consume the comma token
5140a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    getLexer().Lex();
5150a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck
5160a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    // Parse the next operand
51760f923c5e2d752ce5c6e042db8279122eff798ddWesley Peck    if (!ParseOperand(Operands))
5180a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck      return true;
5190a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  }
5204da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
5210a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  // If the instruction requires a memory operand then we need to
5220a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  // replace the last two operands (base+offset) with a single
5230a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  // memory operand.
5240a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  if (Name.startswith("lw") || Name.startswith("sw") ||
5250a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck      Name.startswith("lh") || Name.startswith("sh") ||
5260a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck      Name.startswith("lb") || Name.startswith("sb"))
52741400da31ead2f61d171381c0945dceddd8fc786Wesley Peck    return (ParseMemory(Operands) == NULL);
5284da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
5294da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck  return false;
5304da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck}
5314da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
53291b60c14872883e8dbad73c55ec141ae9f7d4537Wesley Peck/// ParseDirective parses the MBlaze specific directives
5330a67d92938d77b6a8cde6e1676750264b274cebcWesley Peckbool MBlazeAsmParser::ParseDirective(AsmToken DirectiveID) {
53441400da31ead2f61d171381c0945dceddd8fc786Wesley Peck  StringRef IDVal = DirectiveID.getIdentifier();
53541400da31ead2f61d171381c0945dceddd8fc786Wesley Peck  if (IDVal == ".word")
53641400da31ead2f61d171381c0945dceddd8fc786Wesley Peck    return ParseDirectiveWord(2, DirectiveID.getLoc());
5370a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  return true;
5380a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck}
5390a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck
54041400da31ead2f61d171381c0945dceddd8fc786Wesley Peck/// ParseDirectiveWord
54141400da31ead2f61d171381c0945dceddd8fc786Wesley Peck///  ::= .word [ expression (, expression)* ]
54241400da31ead2f61d171381c0945dceddd8fc786Wesley Peckbool MBlazeAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
54341400da31ead2f61d171381c0945dceddd8fc786Wesley Peck  if (getLexer().isNot(AsmToken::EndOfStatement)) {
54441400da31ead2f61d171381c0945dceddd8fc786Wesley Peck    for (;;) {
54541400da31ead2f61d171381c0945dceddd8fc786Wesley Peck      const MCExpr *Value;
546cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      if (getParser().parseExpression(Value))
54741400da31ead2f61d171381c0945dceddd8fc786Wesley Peck        return true;
54841400da31ead2f61d171381c0945dceddd8fc786Wesley Peck
5491ced208be9cab0f994c5df9000da36bc313b2507Eric Christopher      getParser().getStreamer().EmitValue(Value, Size);
55041400da31ead2f61d171381c0945dceddd8fc786Wesley Peck
55141400da31ead2f61d171381c0945dceddd8fc786Wesley Peck      if (getLexer().is(AsmToken::EndOfStatement))
55241400da31ead2f61d171381c0945dceddd8fc786Wesley Peck        break;
55341400da31ead2f61d171381c0945dceddd8fc786Wesley Peck
55441400da31ead2f61d171381c0945dceddd8fc786Wesley Peck      // FIXME: Improve diagnostic.
55541400da31ead2f61d171381c0945dceddd8fc786Wesley Peck      if (getLexer().isNot(AsmToken::Comma))
55641400da31ead2f61d171381c0945dceddd8fc786Wesley Peck        return Error(L, "unexpected token in directive");
55741400da31ead2f61d171381c0945dceddd8fc786Wesley Peck      Parser.Lex();
55841400da31ead2f61d171381c0945dceddd8fc786Wesley Peck    }
55941400da31ead2f61d171381c0945dceddd8fc786Wesley Peck  }
56041400da31ead2f61d171381c0945dceddd8fc786Wesley Peck
56141400da31ead2f61d171381c0945dceddd8fc786Wesley Peck  Parser.Lex();
56241400da31ead2f61d171381c0945dceddd8fc786Wesley Peck  return false;
56341400da31ead2f61d171381c0945dceddd8fc786Wesley Peck}
56441400da31ead2f61d171381c0945dceddd8fc786Wesley Peck
5654da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck/// Force static initialization.
5664da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peckextern "C" void LLVMInitializeMBlazeAsmParser() {
56794b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<MBlazeAsmParser> X(TheMBlazeTarget);
5684da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck}
5694da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck
5704da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck#define GET_REGISTER_MATCHER
5714da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck#define GET_MATCHER_IMPLEMENTATION
5724da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck#include "MBlazeGenAsmMatcher.inc"
573