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