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