1*f0001f41SAnton Korobeynikov //===- MSP430AsmParser.cpp - Parse MSP430 assembly to MCInst instructions -===//
2*f0001f41SAnton Korobeynikov //
3*f0001f41SAnton Korobeynikov //                     The LLVM Compiler Infrastructure
4*f0001f41SAnton Korobeynikov //
5*f0001f41SAnton Korobeynikov // This file is distributed under the University of Illinois Open Source
6*f0001f41SAnton Korobeynikov // License. See LICENSE.TXT for details.
7*f0001f41SAnton Korobeynikov //
8*f0001f41SAnton Korobeynikov //===----------------------------------------------------------------------===//
9*f0001f41SAnton Korobeynikov 
10*f0001f41SAnton Korobeynikov #include "MSP430.h"
11*f0001f41SAnton Korobeynikov #include "MSP430RegisterInfo.h"
12*f0001f41SAnton Korobeynikov #include "MCTargetDesc/MSP430MCTargetDesc.h"
13*f0001f41SAnton Korobeynikov 
14*f0001f41SAnton Korobeynikov #include "llvm/ADT/APInt.h"
15*f0001f41SAnton Korobeynikov #include "llvm/ADT/StringSwitch.h"
16*f0001f41SAnton Korobeynikov #include "llvm/MC/MCContext.h"
17*f0001f41SAnton Korobeynikov #include "llvm/MC/MCExpr.h"
18*f0001f41SAnton Korobeynikov #include "llvm/MC/MCInst.h"
19*f0001f41SAnton Korobeynikov #include "llvm/MC/MCInstBuilder.h"
20*f0001f41SAnton Korobeynikov #include "llvm/MC/MCParser/MCAsmLexer.h"
21*f0001f41SAnton Korobeynikov #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
22*f0001f41SAnton Korobeynikov #include "llvm/MC/MCParser/MCTargetAsmParser.h"
23*f0001f41SAnton Korobeynikov #include "llvm/MC/MCStreamer.h"
24*f0001f41SAnton Korobeynikov #include "llvm/MC/MCSubtargetInfo.h"
25*f0001f41SAnton Korobeynikov #include "llvm/MC/MCSymbol.h"
26*f0001f41SAnton Korobeynikov #include "llvm/MC/MCValue.h"
27*f0001f41SAnton Korobeynikov #include "llvm/Support/Debug.h"
28*f0001f41SAnton Korobeynikov #include "llvm/Support/MathExtras.h"
29*f0001f41SAnton Korobeynikov #include "llvm/Support/TargetRegistry.h"
30*f0001f41SAnton Korobeynikov 
31*f0001f41SAnton Korobeynikov #define DEBUG_TYPE "msp430-asm-parser"
32*f0001f41SAnton Korobeynikov 
33*f0001f41SAnton Korobeynikov using namespace llvm;
34*f0001f41SAnton Korobeynikov 
35*f0001f41SAnton Korobeynikov namespace {
36*f0001f41SAnton Korobeynikov 
37*f0001f41SAnton Korobeynikov /// Parses MSP430 assembly from a stream.
38*f0001f41SAnton Korobeynikov class MSP430AsmParser : public MCTargetAsmParser {
39*f0001f41SAnton Korobeynikov   const MCSubtargetInfo &STI;
40*f0001f41SAnton Korobeynikov   MCAsmParser &Parser;
41*f0001f41SAnton Korobeynikov   const MCRegisterInfo *MRI;
42*f0001f41SAnton Korobeynikov 
43*f0001f41SAnton Korobeynikov   bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
44*f0001f41SAnton Korobeynikov                                OperandVector &Operands, MCStreamer &Out,
45*f0001f41SAnton Korobeynikov                                uint64_t &ErrorInfo,
46*f0001f41SAnton Korobeynikov                                bool MatchingInlineAsm) override;
47*f0001f41SAnton Korobeynikov 
48*f0001f41SAnton Korobeynikov   bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
49*f0001f41SAnton Korobeynikov 
50*f0001f41SAnton Korobeynikov   bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
51*f0001f41SAnton Korobeynikov                         SMLoc NameLoc, OperandVector &Operands) override;
52*f0001f41SAnton Korobeynikov 
53*f0001f41SAnton Korobeynikov   bool ParseDirective(AsmToken DirectiveID) override;
54*f0001f41SAnton Korobeynikov 
55*f0001f41SAnton Korobeynikov   unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
56*f0001f41SAnton Korobeynikov                                       unsigned Kind) override;
57*f0001f41SAnton Korobeynikov 
58*f0001f41SAnton Korobeynikov   bool parseJccInstruction(ParseInstructionInfo &Info, StringRef Name,
59*f0001f41SAnton Korobeynikov                            SMLoc NameLoc, OperandVector &Operands);
60*f0001f41SAnton Korobeynikov 
61*f0001f41SAnton Korobeynikov   bool ParseOperand(OperandVector &Operands);
62*f0001f41SAnton Korobeynikov 
63*f0001f41SAnton Korobeynikov   bool ParseLiteralValues(unsigned Size, SMLoc L);
64*f0001f41SAnton Korobeynikov 
65*f0001f41SAnton Korobeynikov   MCAsmParser &getParser() const { return Parser; }
66*f0001f41SAnton Korobeynikov   MCAsmLexer &getLexer() const { return Parser.getLexer(); }
67*f0001f41SAnton Korobeynikov 
68*f0001f41SAnton Korobeynikov   /// @name Auto-generated Matcher Functions
69*f0001f41SAnton Korobeynikov   /// {
70*f0001f41SAnton Korobeynikov 
71*f0001f41SAnton Korobeynikov #define GET_ASSEMBLER_HEADER
72*f0001f41SAnton Korobeynikov #include "MSP430GenAsmMatcher.inc"
73*f0001f41SAnton Korobeynikov 
74*f0001f41SAnton Korobeynikov   /// }
75*f0001f41SAnton Korobeynikov 
76*f0001f41SAnton Korobeynikov public:
77*f0001f41SAnton Korobeynikov   MSP430AsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
78*f0001f41SAnton Korobeynikov                   const MCInstrInfo &MII, const MCTargetOptions &Options)
79*f0001f41SAnton Korobeynikov       : MCTargetAsmParser(Options, STI, MII), STI(STI), Parser(Parser) {
80*f0001f41SAnton Korobeynikov     MCAsmParserExtension::Initialize(Parser);
81*f0001f41SAnton Korobeynikov     MRI = getContext().getRegisterInfo();
82*f0001f41SAnton Korobeynikov 
83*f0001f41SAnton Korobeynikov     setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
84*f0001f41SAnton Korobeynikov   }
85*f0001f41SAnton Korobeynikov };
86*f0001f41SAnton Korobeynikov 
87*f0001f41SAnton Korobeynikov /// A parsed MSP430 assembly operand.
88*f0001f41SAnton Korobeynikov class MSP430Operand : public MCParsedAsmOperand {
89*f0001f41SAnton Korobeynikov   typedef MCParsedAsmOperand Base;
90*f0001f41SAnton Korobeynikov 
91*f0001f41SAnton Korobeynikov   enum KindTy {
92*f0001f41SAnton Korobeynikov     k_Imm,
93*f0001f41SAnton Korobeynikov     k_Reg,
94*f0001f41SAnton Korobeynikov     k_Tok,
95*f0001f41SAnton Korobeynikov     k_Mem,
96*f0001f41SAnton Korobeynikov     k_IndReg,
97*f0001f41SAnton Korobeynikov     k_PostIndReg
98*f0001f41SAnton Korobeynikov   } Kind;
99*f0001f41SAnton Korobeynikov 
100*f0001f41SAnton Korobeynikov   struct Memory {
101*f0001f41SAnton Korobeynikov     unsigned Reg;
102*f0001f41SAnton Korobeynikov     const MCExpr *Offset;
103*f0001f41SAnton Korobeynikov   };
104*f0001f41SAnton Korobeynikov   union {
105*f0001f41SAnton Korobeynikov     const MCExpr *Imm;
106*f0001f41SAnton Korobeynikov     unsigned      Reg;
107*f0001f41SAnton Korobeynikov     StringRef     Tok;
108*f0001f41SAnton Korobeynikov     Memory        Mem;
109*f0001f41SAnton Korobeynikov   };
110*f0001f41SAnton Korobeynikov 
111*f0001f41SAnton Korobeynikov   SMLoc Start, End;
112*f0001f41SAnton Korobeynikov 
113*f0001f41SAnton Korobeynikov public:
114*f0001f41SAnton Korobeynikov   MSP430Operand(StringRef Tok, SMLoc const &S)
115*f0001f41SAnton Korobeynikov       : Base(), Kind(k_Tok), Tok(Tok), Start(S), End(S) {}
116*f0001f41SAnton Korobeynikov   MSP430Operand(KindTy Kind, unsigned Reg, SMLoc const &S, SMLoc const &E)
117*f0001f41SAnton Korobeynikov       : Base(), Kind(Kind), Reg(Reg), Start(S), End(E) {}
118*f0001f41SAnton Korobeynikov   MSP430Operand(MCExpr const *Imm, SMLoc const &S, SMLoc const &E)
119*f0001f41SAnton Korobeynikov       : Base(), Kind(k_Imm), Imm(Imm), Start(S), End(E) {}
120*f0001f41SAnton Korobeynikov   MSP430Operand(unsigned Reg, MCExpr const *Expr, SMLoc const &S, SMLoc const &E)
121*f0001f41SAnton Korobeynikov       : Base(), Kind(k_Mem), Mem({Reg, Expr}), Start(S), End(E) {}
122*f0001f41SAnton Korobeynikov 
123*f0001f41SAnton Korobeynikov   void addRegOperands(MCInst &Inst, unsigned N) const {
124*f0001f41SAnton Korobeynikov     assert((Kind == k_Reg || Kind == k_IndReg || Kind == k_PostIndReg) &&
125*f0001f41SAnton Korobeynikov         "Unexpected operand kind");
126*f0001f41SAnton Korobeynikov     assert(N == 1 && "Invalid number of operands!");
127*f0001f41SAnton Korobeynikov 
128*f0001f41SAnton Korobeynikov     Inst.addOperand(MCOperand::createReg(Reg));
129*f0001f41SAnton Korobeynikov   }
130*f0001f41SAnton Korobeynikov 
131*f0001f41SAnton Korobeynikov   void addExprOperand(MCInst &Inst, const MCExpr *Expr) const {
132*f0001f41SAnton Korobeynikov     // Add as immediate when possible
133*f0001f41SAnton Korobeynikov     if (!Expr)
134*f0001f41SAnton Korobeynikov       Inst.addOperand(MCOperand::createImm(0));
135*f0001f41SAnton Korobeynikov     else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
136*f0001f41SAnton Korobeynikov       Inst.addOperand(MCOperand::createImm(CE->getValue()));
137*f0001f41SAnton Korobeynikov     else
138*f0001f41SAnton Korobeynikov       Inst.addOperand(MCOperand::createExpr(Expr));
139*f0001f41SAnton Korobeynikov   }
140*f0001f41SAnton Korobeynikov 
141*f0001f41SAnton Korobeynikov   void addImmOperands(MCInst &Inst, unsigned N) const {
142*f0001f41SAnton Korobeynikov     assert(Kind == k_Imm && "Unexpected operand kind");
143*f0001f41SAnton Korobeynikov     assert(N == 1 && "Invalid number of operands!");
144*f0001f41SAnton Korobeynikov 
145*f0001f41SAnton Korobeynikov     addExprOperand(Inst, Imm);
146*f0001f41SAnton Korobeynikov   }
147*f0001f41SAnton Korobeynikov 
148*f0001f41SAnton Korobeynikov   void addMemOperands(MCInst &Inst, unsigned N) const {
149*f0001f41SAnton Korobeynikov     assert(Kind == k_Mem && "Unexpected operand kind");
150*f0001f41SAnton Korobeynikov     assert(N == 2 && "Invalid number of operands");
151*f0001f41SAnton Korobeynikov 
152*f0001f41SAnton Korobeynikov     Inst.addOperand(MCOperand::createReg(Mem.Reg));
153*f0001f41SAnton Korobeynikov     addExprOperand(Inst, Mem.Offset);
154*f0001f41SAnton Korobeynikov   }
155*f0001f41SAnton Korobeynikov 
156*f0001f41SAnton Korobeynikov   bool isReg() const        { return Kind == k_Reg; }
157*f0001f41SAnton Korobeynikov   bool isImm() const        { return Kind == k_Imm; }
158*f0001f41SAnton Korobeynikov   bool isToken() const      { return Kind == k_Tok; }
159*f0001f41SAnton Korobeynikov   bool isMem() const        { return Kind == k_Mem; }
160*f0001f41SAnton Korobeynikov   bool isIndReg() const     { return Kind == k_IndReg; }
161*f0001f41SAnton Korobeynikov   bool isPostIndReg() const { return Kind == k_PostIndReg; }
162*f0001f41SAnton Korobeynikov 
163*f0001f41SAnton Korobeynikov   bool isCGImm() const {
164*f0001f41SAnton Korobeynikov     if (Kind != k_Imm)
165*f0001f41SAnton Korobeynikov       return false;
166*f0001f41SAnton Korobeynikov 
167*f0001f41SAnton Korobeynikov     int64_t Val;
168*f0001f41SAnton Korobeynikov     if (!Imm->evaluateAsAbsolute(Val))
169*f0001f41SAnton Korobeynikov       return false;
170*f0001f41SAnton Korobeynikov 
171*f0001f41SAnton Korobeynikov     if (Val == 0 || Val == 1 || Val == 2 || Val == 4 || Val == 8 || Val == -1)
172*f0001f41SAnton Korobeynikov       return true;
173*f0001f41SAnton Korobeynikov 
174*f0001f41SAnton Korobeynikov     return false;
175*f0001f41SAnton Korobeynikov   }
176*f0001f41SAnton Korobeynikov 
177*f0001f41SAnton Korobeynikov   StringRef getToken() const {
178*f0001f41SAnton Korobeynikov     assert(Kind == k_Tok && "Invalid access!");
179*f0001f41SAnton Korobeynikov     return Tok;
180*f0001f41SAnton Korobeynikov   }
181*f0001f41SAnton Korobeynikov 
182*f0001f41SAnton Korobeynikov   unsigned getReg() const {
183*f0001f41SAnton Korobeynikov     assert(Kind == k_Reg && "Invalid access!");
184*f0001f41SAnton Korobeynikov     return Reg;
185*f0001f41SAnton Korobeynikov   }
186*f0001f41SAnton Korobeynikov 
187*f0001f41SAnton Korobeynikov   void setReg(unsigned RegNo) {
188*f0001f41SAnton Korobeynikov     assert(Kind == k_Reg && "Invalid access!");
189*f0001f41SAnton Korobeynikov     Reg = RegNo;
190*f0001f41SAnton Korobeynikov   }
191*f0001f41SAnton Korobeynikov 
192*f0001f41SAnton Korobeynikov   static std::unique_ptr<MSP430Operand> CreateToken(StringRef Str, SMLoc S) {
193*f0001f41SAnton Korobeynikov     return make_unique<MSP430Operand>(Str, S);
194*f0001f41SAnton Korobeynikov   }
195*f0001f41SAnton Korobeynikov 
196*f0001f41SAnton Korobeynikov   static std::unique_ptr<MSP430Operand> CreateReg(unsigned RegNum, SMLoc S,
197*f0001f41SAnton Korobeynikov                                                   SMLoc E) {
198*f0001f41SAnton Korobeynikov     return make_unique<MSP430Operand>(k_Reg, RegNum, S, E);
199*f0001f41SAnton Korobeynikov   }
200*f0001f41SAnton Korobeynikov 
201*f0001f41SAnton Korobeynikov   static std::unique_ptr<MSP430Operand> CreateImm(const MCExpr *Val, SMLoc S,
202*f0001f41SAnton Korobeynikov                                                   SMLoc E) {
203*f0001f41SAnton Korobeynikov     return make_unique<MSP430Operand>(Val, S, E);
204*f0001f41SAnton Korobeynikov   }
205*f0001f41SAnton Korobeynikov 
206*f0001f41SAnton Korobeynikov   static std::unique_ptr<MSP430Operand> CreateMem(unsigned RegNum,
207*f0001f41SAnton Korobeynikov                                                   const MCExpr *Val,
208*f0001f41SAnton Korobeynikov                                                   SMLoc S, SMLoc E) {
209*f0001f41SAnton Korobeynikov     return make_unique<MSP430Operand>(RegNum, Val, S, E);
210*f0001f41SAnton Korobeynikov   }
211*f0001f41SAnton Korobeynikov 
212*f0001f41SAnton Korobeynikov   static std::unique_ptr<MSP430Operand> CreateIndReg(unsigned RegNum, SMLoc S,
213*f0001f41SAnton Korobeynikov                                                   SMLoc E) {
214*f0001f41SAnton Korobeynikov     return make_unique<MSP430Operand>(k_IndReg, RegNum, S, E);
215*f0001f41SAnton Korobeynikov   }
216*f0001f41SAnton Korobeynikov 
217*f0001f41SAnton Korobeynikov   static std::unique_ptr<MSP430Operand> CreatePostIndReg(unsigned RegNum, SMLoc S,
218*f0001f41SAnton Korobeynikov                                                   SMLoc E) {
219*f0001f41SAnton Korobeynikov     return make_unique<MSP430Operand>(k_PostIndReg, RegNum, S, E);
220*f0001f41SAnton Korobeynikov   }
221*f0001f41SAnton Korobeynikov 
222*f0001f41SAnton Korobeynikov   SMLoc getStartLoc() const { return Start; }
223*f0001f41SAnton Korobeynikov   SMLoc getEndLoc() const { return End; }
224*f0001f41SAnton Korobeynikov 
225*f0001f41SAnton Korobeynikov   virtual void print(raw_ostream &O) const {
226*f0001f41SAnton Korobeynikov     switch (Kind) {
227*f0001f41SAnton Korobeynikov     case k_Tok:
228*f0001f41SAnton Korobeynikov       O << "Token " << Tok;
229*f0001f41SAnton Korobeynikov       break;
230*f0001f41SAnton Korobeynikov     case k_Reg:
231*f0001f41SAnton Korobeynikov       O << "Register " << Reg;
232*f0001f41SAnton Korobeynikov       break;
233*f0001f41SAnton Korobeynikov     case k_Imm:
234*f0001f41SAnton Korobeynikov       O << "Immediate " << *Imm;
235*f0001f41SAnton Korobeynikov       break;
236*f0001f41SAnton Korobeynikov     case k_Mem:
237*f0001f41SAnton Korobeynikov       O << "Memory ";
238*f0001f41SAnton Korobeynikov       O << *Mem.Offset << "(" << Reg << ")";
239*f0001f41SAnton Korobeynikov       break;
240*f0001f41SAnton Korobeynikov     case k_IndReg:
241*f0001f41SAnton Korobeynikov       O << "RegInd " << Reg;
242*f0001f41SAnton Korobeynikov       break;
243*f0001f41SAnton Korobeynikov     case k_PostIndReg:
244*f0001f41SAnton Korobeynikov       O << "PostInc " << Reg;
245*f0001f41SAnton Korobeynikov       break;
246*f0001f41SAnton Korobeynikov     }
247*f0001f41SAnton Korobeynikov   }
248*f0001f41SAnton Korobeynikov };
249*f0001f41SAnton Korobeynikov } // end anonymous namespace
250*f0001f41SAnton Korobeynikov 
251*f0001f41SAnton Korobeynikov bool MSP430AsmParser::MatchAndEmitInstruction(SMLoc Loc, unsigned &Opcode,
252*f0001f41SAnton Korobeynikov                                               OperandVector &Operands,
253*f0001f41SAnton Korobeynikov                                               MCStreamer &Out,
254*f0001f41SAnton Korobeynikov                                               uint64_t &ErrorInfo,
255*f0001f41SAnton Korobeynikov                                               bool MatchingInlineAsm) {
256*f0001f41SAnton Korobeynikov   MCInst Inst;
257*f0001f41SAnton Korobeynikov   unsigned MatchResult =
258*f0001f41SAnton Korobeynikov       MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
259*f0001f41SAnton Korobeynikov 
260*f0001f41SAnton Korobeynikov   switch (MatchResult) {
261*f0001f41SAnton Korobeynikov   case Match_Success:
262*f0001f41SAnton Korobeynikov     Inst.setLoc(Loc);
263*f0001f41SAnton Korobeynikov     Out.EmitInstruction(Inst, STI);
264*f0001f41SAnton Korobeynikov     return false;
265*f0001f41SAnton Korobeynikov   case Match_MnemonicFail:
266*f0001f41SAnton Korobeynikov     return Error(Loc, "invalid instruction mnemonic");
267*f0001f41SAnton Korobeynikov   case Match_InvalidOperand: {
268*f0001f41SAnton Korobeynikov     SMLoc ErrorLoc = Loc;
269*f0001f41SAnton Korobeynikov     if (ErrorInfo != ~0U) {
270*f0001f41SAnton Korobeynikov       if (ErrorInfo >= Operands.size())
271*f0001f41SAnton Korobeynikov         return Error(ErrorLoc, "too few operands for instruction");
272*f0001f41SAnton Korobeynikov 
273*f0001f41SAnton Korobeynikov       ErrorLoc = ((MSP430Operand &)*Operands[ErrorInfo]).getStartLoc();
274*f0001f41SAnton Korobeynikov       if (ErrorLoc == SMLoc())
275*f0001f41SAnton Korobeynikov         ErrorLoc = Loc;
276*f0001f41SAnton Korobeynikov     }
277*f0001f41SAnton Korobeynikov     return Error(ErrorLoc, "invalid operand for instruction");
278*f0001f41SAnton Korobeynikov   }
279*f0001f41SAnton Korobeynikov   default:
280*f0001f41SAnton Korobeynikov     return true;
281*f0001f41SAnton Korobeynikov   }
282*f0001f41SAnton Korobeynikov }
283*f0001f41SAnton Korobeynikov 
284*f0001f41SAnton Korobeynikov // Auto-generated by TableGen
285*f0001f41SAnton Korobeynikov static unsigned MatchRegisterName(StringRef Name);
286*f0001f41SAnton Korobeynikov static unsigned MatchRegisterAltName(StringRef Name);
287*f0001f41SAnton Korobeynikov 
288*f0001f41SAnton Korobeynikov bool MSP430AsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
289*f0001f41SAnton Korobeynikov                                     SMLoc &EndLoc) {
290*f0001f41SAnton Korobeynikov   if (getLexer().getKind() == AsmToken::Identifier) {
291*f0001f41SAnton Korobeynikov     auto Name = getLexer().getTok().getIdentifier().lower();
292*f0001f41SAnton Korobeynikov     RegNo = MatchRegisterName(Name);
293*f0001f41SAnton Korobeynikov     if (RegNo == MSP430::NoRegister) {
294*f0001f41SAnton Korobeynikov       RegNo = MatchRegisterAltName(Name);
295*f0001f41SAnton Korobeynikov       if (RegNo == MSP430::NoRegister)
296*f0001f41SAnton Korobeynikov         return true;
297*f0001f41SAnton Korobeynikov     }
298*f0001f41SAnton Korobeynikov 
299*f0001f41SAnton Korobeynikov     AsmToken const &T = getParser().getTok();
300*f0001f41SAnton Korobeynikov     StartLoc = T.getLoc();
301*f0001f41SAnton Korobeynikov     EndLoc = T.getEndLoc();
302*f0001f41SAnton Korobeynikov     getLexer().Lex(); // eat register token
303*f0001f41SAnton Korobeynikov 
304*f0001f41SAnton Korobeynikov     return false;
305*f0001f41SAnton Korobeynikov   }
306*f0001f41SAnton Korobeynikov 
307*f0001f41SAnton Korobeynikov   return Error(StartLoc, "invalid register name");
308*f0001f41SAnton Korobeynikov }
309*f0001f41SAnton Korobeynikov 
310*f0001f41SAnton Korobeynikov bool MSP430AsmParser::parseJccInstruction(ParseInstructionInfo &Info,
311*f0001f41SAnton Korobeynikov                                           StringRef Name, SMLoc NameLoc,
312*f0001f41SAnton Korobeynikov                                           OperandVector &Operands) {
313*f0001f41SAnton Korobeynikov   if (!Name.startswith_lower("j"))
314*f0001f41SAnton Korobeynikov     return true;
315*f0001f41SAnton Korobeynikov 
316*f0001f41SAnton Korobeynikov   auto CC = Name.drop_front().lower();
317*f0001f41SAnton Korobeynikov   unsigned CondCode;
318*f0001f41SAnton Korobeynikov   if (CC == "ne" || CC == "nz")
319*f0001f41SAnton Korobeynikov     CondCode = MSP430CC::COND_NE;
320*f0001f41SAnton Korobeynikov   else if (CC == "eq" || CC == "z")
321*f0001f41SAnton Korobeynikov     CondCode = MSP430CC::COND_E;
322*f0001f41SAnton Korobeynikov   else if (CC == "lo" || CC == "nc")
323*f0001f41SAnton Korobeynikov     CondCode = MSP430CC::COND_LO;
324*f0001f41SAnton Korobeynikov   else if (CC == "hs" || CC == "c")
325*f0001f41SAnton Korobeynikov     CondCode = MSP430CC::COND_HS;
326*f0001f41SAnton Korobeynikov   else if (CC == "n")
327*f0001f41SAnton Korobeynikov     CondCode = MSP430CC::COND_N;
328*f0001f41SAnton Korobeynikov   else if (CC == "ge")
329*f0001f41SAnton Korobeynikov     CondCode = MSP430CC::COND_GE;
330*f0001f41SAnton Korobeynikov   else if (CC == "l")
331*f0001f41SAnton Korobeynikov     CondCode = MSP430CC::COND_L;
332*f0001f41SAnton Korobeynikov   else if (CC == "mp")
333*f0001f41SAnton Korobeynikov     CondCode = MSP430CC::COND_NONE;
334*f0001f41SAnton Korobeynikov   else
335*f0001f41SAnton Korobeynikov     return Error(NameLoc, "unknown instruction");
336*f0001f41SAnton Korobeynikov 
337*f0001f41SAnton Korobeynikov   if (CondCode == (unsigned)MSP430CC::COND_NONE)
338*f0001f41SAnton Korobeynikov     Operands.push_back(MSP430Operand::CreateToken("jmp", NameLoc));
339*f0001f41SAnton Korobeynikov   else {
340*f0001f41SAnton Korobeynikov     Operands.push_back(MSP430Operand::CreateToken("j", NameLoc));
341*f0001f41SAnton Korobeynikov     const MCExpr *CCode = MCConstantExpr::create(CondCode, getContext());
342*f0001f41SAnton Korobeynikov     Operands.push_back(MSP430Operand::CreateImm(CCode, SMLoc(), SMLoc()));
343*f0001f41SAnton Korobeynikov   }
344*f0001f41SAnton Korobeynikov 
345*f0001f41SAnton Korobeynikov   // Skip optional '$' sign.
346*f0001f41SAnton Korobeynikov   if (getLexer().getKind() == AsmToken::Dollar)
347*f0001f41SAnton Korobeynikov     getLexer().Lex(); // Eat '$'
348*f0001f41SAnton Korobeynikov 
349*f0001f41SAnton Korobeynikov   const MCExpr *Val;
350*f0001f41SAnton Korobeynikov   SMLoc ExprLoc = getLexer().getLoc();
351*f0001f41SAnton Korobeynikov   if (getParser().parseExpression(Val))
352*f0001f41SAnton Korobeynikov     return Error(ExprLoc, "expected expression operand");
353*f0001f41SAnton Korobeynikov 
354*f0001f41SAnton Korobeynikov   int64_t Res;
355*f0001f41SAnton Korobeynikov   if (Val->evaluateAsAbsolute(Res))
356*f0001f41SAnton Korobeynikov     if (Res < -512 || Res > 511)
357*f0001f41SAnton Korobeynikov       return Error(ExprLoc, "invalid jump offset");
358*f0001f41SAnton Korobeynikov 
359*f0001f41SAnton Korobeynikov   Operands.push_back(MSP430Operand::CreateImm(Val, ExprLoc,
360*f0001f41SAnton Korobeynikov     getLexer().getLoc()));
361*f0001f41SAnton Korobeynikov 
362*f0001f41SAnton Korobeynikov   if (getLexer().isNot(AsmToken::EndOfStatement)) {
363*f0001f41SAnton Korobeynikov     SMLoc Loc = getLexer().getLoc();
364*f0001f41SAnton Korobeynikov     getParser().eatToEndOfStatement();
365*f0001f41SAnton Korobeynikov     return Error(Loc, "unexpected token");
366*f0001f41SAnton Korobeynikov   }
367*f0001f41SAnton Korobeynikov 
368*f0001f41SAnton Korobeynikov   getParser().Lex(); // Consume the EndOfStatement.
369*f0001f41SAnton Korobeynikov   return false;
370*f0001f41SAnton Korobeynikov }
371*f0001f41SAnton Korobeynikov 
372*f0001f41SAnton Korobeynikov bool MSP430AsmParser::ParseInstruction(ParseInstructionInfo &Info,
373*f0001f41SAnton Korobeynikov                                        StringRef Name, SMLoc NameLoc,
374*f0001f41SAnton Korobeynikov                                        OperandVector &Operands) {
375*f0001f41SAnton Korobeynikov   // Drop .w suffix
376*f0001f41SAnton Korobeynikov   if (Name.endswith_lower(".w"))
377*f0001f41SAnton Korobeynikov     Name = Name.drop_back(2);
378*f0001f41SAnton Korobeynikov 
379*f0001f41SAnton Korobeynikov   if (!parseJccInstruction(Info, Name, NameLoc, Operands))
380*f0001f41SAnton Korobeynikov     return false;
381*f0001f41SAnton Korobeynikov 
382*f0001f41SAnton Korobeynikov   // First operand is instruction mnemonic
383*f0001f41SAnton Korobeynikov   Operands.push_back(MSP430Operand::CreateToken(Name, NameLoc));
384*f0001f41SAnton Korobeynikov 
385*f0001f41SAnton Korobeynikov   // If there are no more operands, then finish
386*f0001f41SAnton Korobeynikov   if (getLexer().is(AsmToken::EndOfStatement))
387*f0001f41SAnton Korobeynikov     return false;
388*f0001f41SAnton Korobeynikov 
389*f0001f41SAnton Korobeynikov   // Parse first operand
390*f0001f41SAnton Korobeynikov   if (ParseOperand(Operands))
391*f0001f41SAnton Korobeynikov     return true;
392*f0001f41SAnton Korobeynikov 
393*f0001f41SAnton Korobeynikov   // Parse second operand if any
394*f0001f41SAnton Korobeynikov   if (getLexer().is(AsmToken::Comma)) {
395*f0001f41SAnton Korobeynikov     getLexer().Lex(); // Eat ','
396*f0001f41SAnton Korobeynikov     if (ParseOperand(Operands))
397*f0001f41SAnton Korobeynikov       return true;
398*f0001f41SAnton Korobeynikov   }
399*f0001f41SAnton Korobeynikov 
400*f0001f41SAnton Korobeynikov   if (getLexer().isNot(AsmToken::EndOfStatement)) {
401*f0001f41SAnton Korobeynikov     SMLoc Loc = getLexer().getLoc();
402*f0001f41SAnton Korobeynikov     getParser().eatToEndOfStatement();
403*f0001f41SAnton Korobeynikov     return Error(Loc, "unexpected token");
404*f0001f41SAnton Korobeynikov   }
405*f0001f41SAnton Korobeynikov 
406*f0001f41SAnton Korobeynikov   getParser().Lex(); // Consume the EndOfStatement.
407*f0001f41SAnton Korobeynikov   return false;
408*f0001f41SAnton Korobeynikov }
409*f0001f41SAnton Korobeynikov 
410*f0001f41SAnton Korobeynikov bool MSP430AsmParser::ParseDirective(AsmToken DirectiveID) {
411*f0001f41SAnton Korobeynikov   StringRef IDVal = DirectiveID.getIdentifier();
412*f0001f41SAnton Korobeynikov   if (IDVal.lower() == ".long") {
413*f0001f41SAnton Korobeynikov     ParseLiteralValues(4, DirectiveID.getLoc());
414*f0001f41SAnton Korobeynikov   } else if (IDVal.lower() == ".word" || IDVal.lower() == ".short") {
415*f0001f41SAnton Korobeynikov     ParseLiteralValues(2, DirectiveID.getLoc());
416*f0001f41SAnton Korobeynikov   } else if (IDVal.lower() == ".byte") {
417*f0001f41SAnton Korobeynikov     ParseLiteralValues(1, DirectiveID.getLoc());
418*f0001f41SAnton Korobeynikov   }
419*f0001f41SAnton Korobeynikov   return true;
420*f0001f41SAnton Korobeynikov }
421*f0001f41SAnton Korobeynikov 
422*f0001f41SAnton Korobeynikov bool MSP430AsmParser::ParseOperand(OperandVector &Operands) {
423*f0001f41SAnton Korobeynikov   switch (getLexer().getKind()) {
424*f0001f41SAnton Korobeynikov     default: return true;
425*f0001f41SAnton Korobeynikov     case AsmToken::Identifier: {
426*f0001f41SAnton Korobeynikov       // try rN
427*f0001f41SAnton Korobeynikov       unsigned RegNo;
428*f0001f41SAnton Korobeynikov       SMLoc StartLoc, EndLoc;
429*f0001f41SAnton Korobeynikov       if (!ParseRegister(RegNo, StartLoc, EndLoc)) {
430*f0001f41SAnton Korobeynikov         Operands.push_back(MSP430Operand::CreateReg(RegNo, StartLoc, EndLoc));
431*f0001f41SAnton Korobeynikov         return false;
432*f0001f41SAnton Korobeynikov       }
433*f0001f41SAnton Korobeynikov       LLVM_FALLTHROUGH;
434*f0001f41SAnton Korobeynikov     }
435*f0001f41SAnton Korobeynikov     case AsmToken::Integer:
436*f0001f41SAnton Korobeynikov     case AsmToken::Plus:
437*f0001f41SAnton Korobeynikov     case AsmToken::Minus: {
438*f0001f41SAnton Korobeynikov       SMLoc StartLoc = getParser().getTok().getLoc();
439*f0001f41SAnton Korobeynikov       const MCExpr *Val;
440*f0001f41SAnton Korobeynikov       // Try constexpr[(rN)]
441*f0001f41SAnton Korobeynikov       if (!getParser().parseExpression(Val)) {
442*f0001f41SAnton Korobeynikov         unsigned RegNo = MSP430::PC;
443*f0001f41SAnton Korobeynikov         SMLoc EndLoc = getParser().getTok().getLoc();
444*f0001f41SAnton Korobeynikov         // Try (rN)
445*f0001f41SAnton Korobeynikov         if (getLexer().getKind() == AsmToken::LParen) {
446*f0001f41SAnton Korobeynikov           getLexer().Lex(); // Eat '('
447*f0001f41SAnton Korobeynikov           SMLoc RegStartLoc;
448*f0001f41SAnton Korobeynikov           if (ParseRegister(RegNo, RegStartLoc, EndLoc))
449*f0001f41SAnton Korobeynikov             return true;
450*f0001f41SAnton Korobeynikov           if (getLexer().getKind() != AsmToken::RParen)
451*f0001f41SAnton Korobeynikov             return true;
452*f0001f41SAnton Korobeynikov           EndLoc = getParser().getTok().getEndLoc();
453*f0001f41SAnton Korobeynikov           getLexer().Lex(); // Eat ')'
454*f0001f41SAnton Korobeynikov         }
455*f0001f41SAnton Korobeynikov         Operands.push_back(MSP430Operand::CreateMem(RegNo, Val, StartLoc,
456*f0001f41SAnton Korobeynikov           EndLoc));
457*f0001f41SAnton Korobeynikov         return false;
458*f0001f41SAnton Korobeynikov       }
459*f0001f41SAnton Korobeynikov       return true;
460*f0001f41SAnton Korobeynikov     }
461*f0001f41SAnton Korobeynikov     case AsmToken::Amp: {
462*f0001f41SAnton Korobeynikov       // Try &constexpr
463*f0001f41SAnton Korobeynikov       SMLoc StartLoc = getParser().getTok().getLoc();
464*f0001f41SAnton Korobeynikov       getLexer().Lex(); // Eat '&'
465*f0001f41SAnton Korobeynikov       const MCExpr *Val;
466*f0001f41SAnton Korobeynikov       if (!getParser().parseExpression(Val)) {
467*f0001f41SAnton Korobeynikov         SMLoc EndLoc = getParser().getTok().getLoc();
468*f0001f41SAnton Korobeynikov         Operands.push_back(MSP430Operand::CreateMem(MSP430::SR, Val, StartLoc,
469*f0001f41SAnton Korobeynikov           EndLoc));
470*f0001f41SAnton Korobeynikov         return false;
471*f0001f41SAnton Korobeynikov       }
472*f0001f41SAnton Korobeynikov       return true;
473*f0001f41SAnton Korobeynikov     }
474*f0001f41SAnton Korobeynikov     case AsmToken::At: {
475*f0001f41SAnton Korobeynikov       // Try @rN[+]
476*f0001f41SAnton Korobeynikov       SMLoc StartLoc = getParser().getTok().getLoc();
477*f0001f41SAnton Korobeynikov       getLexer().Lex(); // Eat '@'
478*f0001f41SAnton Korobeynikov       unsigned RegNo;
479*f0001f41SAnton Korobeynikov       SMLoc RegStartLoc, EndLoc;
480*f0001f41SAnton Korobeynikov       if (ParseRegister(RegNo, RegStartLoc, EndLoc))
481*f0001f41SAnton Korobeynikov         return true;
482*f0001f41SAnton Korobeynikov       if (getLexer().getKind() == AsmToken::Plus) {
483*f0001f41SAnton Korobeynikov         Operands.push_back(MSP430Operand::CreatePostIndReg(RegNo, StartLoc, EndLoc));
484*f0001f41SAnton Korobeynikov         getLexer().Lex(); // Eat '+'
485*f0001f41SAnton Korobeynikov         return false;
486*f0001f41SAnton Korobeynikov       }
487*f0001f41SAnton Korobeynikov       Operands.push_back(MSP430Operand::CreateIndReg(RegNo, StartLoc, EndLoc));
488*f0001f41SAnton Korobeynikov       return false;
489*f0001f41SAnton Korobeynikov     }
490*f0001f41SAnton Korobeynikov     case AsmToken::Hash:
491*f0001f41SAnton Korobeynikov       // Try #constexpr
492*f0001f41SAnton Korobeynikov       SMLoc StartLoc = getParser().getTok().getLoc();
493*f0001f41SAnton Korobeynikov       getLexer().Lex(); // Eat '#'
494*f0001f41SAnton Korobeynikov       const MCExpr *Val;
495*f0001f41SAnton Korobeynikov       if (!getParser().parseExpression(Val)) {
496*f0001f41SAnton Korobeynikov         SMLoc EndLoc = getParser().getTok().getLoc();
497*f0001f41SAnton Korobeynikov         Operands.push_back(MSP430Operand::CreateImm(Val, StartLoc, EndLoc));
498*f0001f41SAnton Korobeynikov         return false;
499*f0001f41SAnton Korobeynikov       }
500*f0001f41SAnton Korobeynikov       return true;
501*f0001f41SAnton Korobeynikov   }
502*f0001f41SAnton Korobeynikov }
503*f0001f41SAnton Korobeynikov 
504*f0001f41SAnton Korobeynikov bool MSP430AsmParser::ParseLiteralValues(unsigned Size, SMLoc L) {
505*f0001f41SAnton Korobeynikov   auto parseOne = [&]() -> bool {
506*f0001f41SAnton Korobeynikov     const MCExpr *Value;
507*f0001f41SAnton Korobeynikov     if (getParser().parseExpression(Value))
508*f0001f41SAnton Korobeynikov       return true;
509*f0001f41SAnton Korobeynikov     getParser().getStreamer().EmitValue(Value, Size, L);
510*f0001f41SAnton Korobeynikov     return false;
511*f0001f41SAnton Korobeynikov   };
512*f0001f41SAnton Korobeynikov   return (parseMany(parseOne));
513*f0001f41SAnton Korobeynikov }
514*f0001f41SAnton Korobeynikov 
515*f0001f41SAnton Korobeynikov extern "C" void LLVMInitializeMSP430AsmParser() {
516*f0001f41SAnton Korobeynikov   RegisterMCAsmParser<MSP430AsmParser> X(getTheMSP430Target());
517*f0001f41SAnton Korobeynikov }
518*f0001f41SAnton Korobeynikov 
519*f0001f41SAnton Korobeynikov #define GET_REGISTER_MATCHER
520*f0001f41SAnton Korobeynikov #define GET_MATCHER_IMPLEMENTATION
521*f0001f41SAnton Korobeynikov #include "MSP430GenAsmMatcher.inc"
522*f0001f41SAnton Korobeynikov 
523*f0001f41SAnton Korobeynikov static unsigned convertGR16ToGR8(unsigned Reg) {
524*f0001f41SAnton Korobeynikov   switch (Reg) {
525*f0001f41SAnton Korobeynikov   default:
526*f0001f41SAnton Korobeynikov     llvm_unreachable("Unknown GR16 register");
527*f0001f41SAnton Korobeynikov   case MSP430::PC:  return MSP430::PCB;
528*f0001f41SAnton Korobeynikov   case MSP430::SP:  return MSP430::SPB;
529*f0001f41SAnton Korobeynikov   case MSP430::SR:  return MSP430::SRB;
530*f0001f41SAnton Korobeynikov   case MSP430::CG:  return MSP430::CGB;
531*f0001f41SAnton Korobeynikov   case MSP430::FP:  return MSP430::FPB;
532*f0001f41SAnton Korobeynikov   case MSP430::R5:  return MSP430::R5B;
533*f0001f41SAnton Korobeynikov   case MSP430::R6:  return MSP430::R6B;
534*f0001f41SAnton Korobeynikov   case MSP430::R7:  return MSP430::R7B;
535*f0001f41SAnton Korobeynikov   case MSP430::R8:  return MSP430::R8B;
536*f0001f41SAnton Korobeynikov   case MSP430::R9:  return MSP430::R9B;
537*f0001f41SAnton Korobeynikov   case MSP430::R10: return MSP430::R10B;
538*f0001f41SAnton Korobeynikov   case MSP430::R11: return MSP430::R11B;
539*f0001f41SAnton Korobeynikov   case MSP430::R12: return MSP430::R12B;
540*f0001f41SAnton Korobeynikov   case MSP430::R13: return MSP430::R13B;
541*f0001f41SAnton Korobeynikov   case MSP430::R14: return MSP430::R14B;
542*f0001f41SAnton Korobeynikov   case MSP430::R15: return MSP430::R15B;
543*f0001f41SAnton Korobeynikov   }
544*f0001f41SAnton Korobeynikov }
545*f0001f41SAnton Korobeynikov 
546*f0001f41SAnton Korobeynikov unsigned MSP430AsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
547*f0001f41SAnton Korobeynikov                                                      unsigned Kind) {
548*f0001f41SAnton Korobeynikov   MSP430Operand &Op = static_cast<MSP430Operand &>(AsmOp);
549*f0001f41SAnton Korobeynikov 
550*f0001f41SAnton Korobeynikov   if (!Op.isReg())
551*f0001f41SAnton Korobeynikov     return Match_InvalidOperand;
552*f0001f41SAnton Korobeynikov 
553*f0001f41SAnton Korobeynikov   unsigned Reg = Op.getReg();
554*f0001f41SAnton Korobeynikov   bool isGR16 =
555*f0001f41SAnton Korobeynikov       MSP430MCRegisterClasses[MSP430::GR16RegClassID].contains(Reg);
556*f0001f41SAnton Korobeynikov 
557*f0001f41SAnton Korobeynikov   if (isGR16 && (Kind == MCK_GR8)) {
558*f0001f41SAnton Korobeynikov     Op.setReg(convertGR16ToGR8(Reg));
559*f0001f41SAnton Korobeynikov     return Match_Success;
560*f0001f41SAnton Korobeynikov   }
561*f0001f41SAnton Korobeynikov 
562*f0001f41SAnton Korobeynikov   return Match_InvalidOperand;
563*f0001f41SAnton Korobeynikov }
564