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" 26*89b57061SReid 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) 117f0001f41SAnton Korobeynikov : Base(), Kind(k_Tok), Tok(Tok), Start(S), End(S) {} 118f0001f41SAnton Korobeynikov MSP430Operand(KindTy Kind, unsigned Reg, SMLoc const &S, SMLoc const &E) 119f0001f41SAnton Korobeynikov : Base(), Kind(Kind), Reg(Reg), Start(S), End(E) {} 120f0001f41SAnton Korobeynikov MSP430Operand(MCExpr const *Imm, SMLoc const &S, SMLoc const &E) 121f0001f41SAnton Korobeynikov : Base(), Kind(k_Imm), Imm(Imm), Start(S), End(E) {} 122f0001f41SAnton Korobeynikov MSP430Operand(unsigned Reg, MCExpr const *Expr, SMLoc const &S, SMLoc const &E) 123f0001f41SAnton Korobeynikov : Base(), Kind(k_Mem), Mem({Reg, Expr}), Start(S), End(E) {} 124f0001f41SAnton Korobeynikov 125f0001f41SAnton Korobeynikov void addRegOperands(MCInst &Inst, unsigned N) const { 126f0001f41SAnton Korobeynikov assert((Kind == k_Reg || Kind == k_IndReg || Kind == k_PostIndReg) && 127f0001f41SAnton Korobeynikov "Unexpected operand kind"); 128f0001f41SAnton Korobeynikov assert(N == 1 && "Invalid number of operands!"); 129f0001f41SAnton Korobeynikov 130f0001f41SAnton Korobeynikov Inst.addOperand(MCOperand::createReg(Reg)); 131f0001f41SAnton Korobeynikov } 132f0001f41SAnton Korobeynikov 133f0001f41SAnton Korobeynikov void addExprOperand(MCInst &Inst, const MCExpr *Expr) const { 134f0001f41SAnton Korobeynikov // Add as immediate when possible 135f0001f41SAnton Korobeynikov if (!Expr) 136f0001f41SAnton Korobeynikov Inst.addOperand(MCOperand::createImm(0)); 137f0001f41SAnton Korobeynikov else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 138f0001f41SAnton Korobeynikov Inst.addOperand(MCOperand::createImm(CE->getValue())); 139f0001f41SAnton Korobeynikov else 140f0001f41SAnton Korobeynikov Inst.addOperand(MCOperand::createExpr(Expr)); 141f0001f41SAnton Korobeynikov } 142f0001f41SAnton Korobeynikov 143f0001f41SAnton Korobeynikov void addImmOperands(MCInst &Inst, unsigned N) const { 144f0001f41SAnton Korobeynikov assert(Kind == k_Imm && "Unexpected operand kind"); 145f0001f41SAnton Korobeynikov assert(N == 1 && "Invalid number of operands!"); 146f0001f41SAnton Korobeynikov 147f0001f41SAnton Korobeynikov addExprOperand(Inst, Imm); 148f0001f41SAnton Korobeynikov } 149f0001f41SAnton Korobeynikov 150f0001f41SAnton Korobeynikov void addMemOperands(MCInst &Inst, unsigned N) const { 151f0001f41SAnton Korobeynikov assert(Kind == k_Mem && "Unexpected operand kind"); 152f0001f41SAnton Korobeynikov assert(N == 2 && "Invalid number of operands"); 153f0001f41SAnton Korobeynikov 154f0001f41SAnton Korobeynikov Inst.addOperand(MCOperand::createReg(Mem.Reg)); 155f0001f41SAnton Korobeynikov addExprOperand(Inst, Mem.Offset); 156f0001f41SAnton Korobeynikov } 157f0001f41SAnton Korobeynikov 158a19461d9SLogan Smith bool isReg() const override { return Kind == k_Reg; } 159a19461d9SLogan Smith bool isImm() const override { return Kind == k_Imm; } 160a19461d9SLogan Smith bool isToken() const override { return Kind == k_Tok; } 161a19461d9SLogan Smith bool isMem() const override { return Kind == k_Mem; } 162f0001f41SAnton Korobeynikov bool isIndReg() const { return Kind == k_IndReg; } 163f0001f41SAnton Korobeynikov bool isPostIndReg() const { return Kind == k_PostIndReg; } 164f0001f41SAnton Korobeynikov 165f0001f41SAnton Korobeynikov bool isCGImm() const { 166f0001f41SAnton Korobeynikov if (Kind != k_Imm) 167f0001f41SAnton Korobeynikov return false; 168f0001f41SAnton Korobeynikov 169f0001f41SAnton Korobeynikov int64_t Val; 170f0001f41SAnton Korobeynikov if (!Imm->evaluateAsAbsolute(Val)) 171f0001f41SAnton Korobeynikov return false; 172f0001f41SAnton Korobeynikov 173f0001f41SAnton Korobeynikov if (Val == 0 || Val == 1 || Val == 2 || Val == 4 || Val == 8 || Val == -1) 174f0001f41SAnton Korobeynikov return true; 175f0001f41SAnton Korobeynikov 176f0001f41SAnton Korobeynikov return false; 177f0001f41SAnton Korobeynikov } 178f0001f41SAnton Korobeynikov 179f0001f41SAnton Korobeynikov StringRef getToken() const { 180f0001f41SAnton Korobeynikov assert(Kind == k_Tok && "Invalid access!"); 181f0001f41SAnton Korobeynikov return Tok; 182f0001f41SAnton Korobeynikov } 183f0001f41SAnton Korobeynikov 184a19461d9SLogan Smith unsigned getReg() const override { 185f0001f41SAnton Korobeynikov assert(Kind == k_Reg && "Invalid access!"); 186f0001f41SAnton Korobeynikov return Reg; 187f0001f41SAnton Korobeynikov } 188f0001f41SAnton Korobeynikov 189f0001f41SAnton Korobeynikov void setReg(unsigned RegNo) { 190f0001f41SAnton Korobeynikov assert(Kind == k_Reg && "Invalid access!"); 191f0001f41SAnton Korobeynikov Reg = RegNo; 192f0001f41SAnton Korobeynikov } 193f0001f41SAnton Korobeynikov 194f0001f41SAnton Korobeynikov static std::unique_ptr<MSP430Operand> CreateToken(StringRef Str, SMLoc S) { 1950eaee545SJonas Devlieghere return std::make_unique<MSP430Operand>(Str, S); 196f0001f41SAnton Korobeynikov } 197f0001f41SAnton Korobeynikov 198f0001f41SAnton Korobeynikov static std::unique_ptr<MSP430Operand> CreateReg(unsigned RegNum, SMLoc S, 199f0001f41SAnton Korobeynikov SMLoc E) { 2000eaee545SJonas Devlieghere return std::make_unique<MSP430Operand>(k_Reg, RegNum, S, E); 201f0001f41SAnton Korobeynikov } 202f0001f41SAnton Korobeynikov 203f0001f41SAnton Korobeynikov static std::unique_ptr<MSP430Operand> CreateImm(const MCExpr *Val, SMLoc S, 204f0001f41SAnton Korobeynikov SMLoc E) { 2050eaee545SJonas Devlieghere return std::make_unique<MSP430Operand>(Val, S, E); 206f0001f41SAnton Korobeynikov } 207f0001f41SAnton Korobeynikov 208f0001f41SAnton Korobeynikov static std::unique_ptr<MSP430Operand> CreateMem(unsigned RegNum, 209f0001f41SAnton Korobeynikov const MCExpr *Val, 210f0001f41SAnton Korobeynikov SMLoc S, SMLoc E) { 2110eaee545SJonas Devlieghere return std::make_unique<MSP430Operand>(RegNum, Val, S, E); 212f0001f41SAnton Korobeynikov } 213f0001f41SAnton Korobeynikov 214f0001f41SAnton Korobeynikov static std::unique_ptr<MSP430Operand> CreateIndReg(unsigned RegNum, SMLoc S, 215f0001f41SAnton Korobeynikov SMLoc E) { 2160eaee545SJonas Devlieghere return std::make_unique<MSP430Operand>(k_IndReg, RegNum, S, E); 217f0001f41SAnton Korobeynikov } 218f0001f41SAnton Korobeynikov 219f0001f41SAnton Korobeynikov static std::unique_ptr<MSP430Operand> CreatePostIndReg(unsigned RegNum, SMLoc S, 220f0001f41SAnton Korobeynikov SMLoc E) { 2210eaee545SJonas Devlieghere return std::make_unique<MSP430Operand>(k_PostIndReg, RegNum, S, E); 222f0001f41SAnton Korobeynikov } 223f0001f41SAnton Korobeynikov 224a19461d9SLogan Smith SMLoc getStartLoc() const override { return Start; } 225a19461d9SLogan Smith SMLoc getEndLoc() const override { return End; } 226f0001f41SAnton Korobeynikov 227a19461d9SLogan Smith void print(raw_ostream &O) const override { 228f0001f41SAnton Korobeynikov switch (Kind) { 229f0001f41SAnton Korobeynikov case k_Tok: 230f0001f41SAnton Korobeynikov O << "Token " << Tok; 231f0001f41SAnton Korobeynikov break; 232f0001f41SAnton Korobeynikov case k_Reg: 233f0001f41SAnton Korobeynikov O << "Register " << Reg; 234f0001f41SAnton Korobeynikov break; 235f0001f41SAnton Korobeynikov case k_Imm: 236f0001f41SAnton Korobeynikov O << "Immediate " << *Imm; 237f0001f41SAnton Korobeynikov break; 238f0001f41SAnton Korobeynikov case k_Mem: 239f0001f41SAnton Korobeynikov O << "Memory "; 240f0001f41SAnton Korobeynikov O << *Mem.Offset << "(" << Reg << ")"; 241f0001f41SAnton Korobeynikov break; 242f0001f41SAnton Korobeynikov case k_IndReg: 243f0001f41SAnton Korobeynikov O << "RegInd " << Reg; 244f0001f41SAnton Korobeynikov break; 245f0001f41SAnton Korobeynikov case k_PostIndReg: 246f0001f41SAnton Korobeynikov O << "PostInc " << Reg; 247f0001f41SAnton Korobeynikov break; 248f0001f41SAnton Korobeynikov } 249f0001f41SAnton Korobeynikov } 250f0001f41SAnton Korobeynikov }; 251f0001f41SAnton Korobeynikov } // end anonymous namespace 252f0001f41SAnton Korobeynikov 253f0001f41SAnton Korobeynikov bool MSP430AsmParser::MatchAndEmitInstruction(SMLoc Loc, unsigned &Opcode, 254f0001f41SAnton Korobeynikov OperandVector &Operands, 255f0001f41SAnton Korobeynikov MCStreamer &Out, 256f0001f41SAnton Korobeynikov uint64_t &ErrorInfo, 257f0001f41SAnton Korobeynikov bool MatchingInlineAsm) { 258f0001f41SAnton Korobeynikov MCInst Inst; 259f0001f41SAnton Korobeynikov unsigned MatchResult = 260f0001f41SAnton Korobeynikov MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); 261f0001f41SAnton Korobeynikov 262f0001f41SAnton Korobeynikov switch (MatchResult) { 263f0001f41SAnton Korobeynikov case Match_Success: 264f0001f41SAnton Korobeynikov Inst.setLoc(Loc); 265bcd24b2dSFangrui Song Out.emitInstruction(Inst, STI); 266f0001f41SAnton Korobeynikov return false; 267f0001f41SAnton Korobeynikov case Match_MnemonicFail: 268f0001f41SAnton Korobeynikov return Error(Loc, "invalid instruction mnemonic"); 269f0001f41SAnton Korobeynikov case Match_InvalidOperand: { 270f0001f41SAnton Korobeynikov SMLoc ErrorLoc = Loc; 271f0001f41SAnton Korobeynikov if (ErrorInfo != ~0U) { 272f0001f41SAnton Korobeynikov if (ErrorInfo >= Operands.size()) 273f0001f41SAnton Korobeynikov return Error(ErrorLoc, "too few operands for instruction"); 274f0001f41SAnton Korobeynikov 275f0001f41SAnton Korobeynikov ErrorLoc = ((MSP430Operand &)*Operands[ErrorInfo]).getStartLoc(); 276f0001f41SAnton Korobeynikov if (ErrorLoc == SMLoc()) 277f0001f41SAnton Korobeynikov ErrorLoc = Loc; 278f0001f41SAnton Korobeynikov } 279f0001f41SAnton Korobeynikov return Error(ErrorLoc, "invalid operand for instruction"); 280f0001f41SAnton Korobeynikov } 281f0001f41SAnton Korobeynikov default: 282f0001f41SAnton Korobeynikov return true; 283f0001f41SAnton Korobeynikov } 284f0001f41SAnton Korobeynikov } 285f0001f41SAnton Korobeynikov 286f0001f41SAnton Korobeynikov // Auto-generated by TableGen 287f0001f41SAnton Korobeynikov static unsigned MatchRegisterName(StringRef Name); 288f0001f41SAnton Korobeynikov static unsigned MatchRegisterAltName(StringRef Name); 289f0001f41SAnton Korobeynikov 290f0001f41SAnton Korobeynikov bool MSP430AsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 291f0001f41SAnton Korobeynikov SMLoc &EndLoc) { 2928d5bf042SEric Astor switch (tryParseRegister(RegNo, StartLoc, EndLoc)) { 2938d5bf042SEric Astor case MatchOperand_ParseFail: 2948d5bf042SEric Astor return Error(StartLoc, "invalid register name"); 2958d5bf042SEric Astor case MatchOperand_Success: 2968d5bf042SEric Astor return false; 2978d5bf042SEric Astor case MatchOperand_NoMatch: 2988d5bf042SEric Astor return true; 2998d5bf042SEric Astor } 3008d5bf042SEric Astor 3018d5bf042SEric Astor llvm_unreachable("unknown match result type"); 3028d5bf042SEric Astor } 3038d5bf042SEric Astor 3048d5bf042SEric Astor OperandMatchResultTy MSP430AsmParser::tryParseRegister(unsigned &RegNo, 3058d5bf042SEric Astor SMLoc &StartLoc, 3068d5bf042SEric Astor SMLoc &EndLoc) { 307f0001f41SAnton Korobeynikov if (getLexer().getKind() == AsmToken::Identifier) { 308f0001f41SAnton Korobeynikov auto Name = getLexer().getTok().getIdentifier().lower(); 309f0001f41SAnton Korobeynikov RegNo = MatchRegisterName(Name); 310f0001f41SAnton Korobeynikov if (RegNo == MSP430::NoRegister) { 311f0001f41SAnton Korobeynikov RegNo = MatchRegisterAltName(Name); 312f0001f41SAnton Korobeynikov if (RegNo == MSP430::NoRegister) 3138d5bf042SEric Astor return MatchOperand_NoMatch; 314f0001f41SAnton Korobeynikov } 315f0001f41SAnton Korobeynikov 316f0001f41SAnton Korobeynikov AsmToken const &T = getParser().getTok(); 317f0001f41SAnton Korobeynikov StartLoc = T.getLoc(); 318f0001f41SAnton Korobeynikov EndLoc = T.getEndLoc(); 319f0001f41SAnton Korobeynikov getLexer().Lex(); // eat register token 320f0001f41SAnton Korobeynikov 3218d5bf042SEric Astor return MatchOperand_Success; 322f0001f41SAnton Korobeynikov } 323f0001f41SAnton Korobeynikov 3248d5bf042SEric Astor return MatchOperand_ParseFail; 325f0001f41SAnton Korobeynikov } 326f0001f41SAnton Korobeynikov 327f0001f41SAnton Korobeynikov bool MSP430AsmParser::parseJccInstruction(ParseInstructionInfo &Info, 328f0001f41SAnton Korobeynikov StringRef Name, SMLoc NameLoc, 329f0001f41SAnton Korobeynikov OperandVector &Operands) { 33042f74e82SMartin Storsjö if (!Name.startswith_insensitive("j")) 331f0001f41SAnton Korobeynikov return true; 332f0001f41SAnton Korobeynikov 333f0001f41SAnton Korobeynikov auto CC = Name.drop_front().lower(); 334f0001f41SAnton Korobeynikov unsigned CondCode; 335f0001f41SAnton Korobeynikov if (CC == "ne" || CC == "nz") 336f0001f41SAnton Korobeynikov CondCode = MSP430CC::COND_NE; 337f0001f41SAnton Korobeynikov else if (CC == "eq" || CC == "z") 338f0001f41SAnton Korobeynikov CondCode = MSP430CC::COND_E; 339f0001f41SAnton Korobeynikov else if (CC == "lo" || CC == "nc") 340f0001f41SAnton Korobeynikov CondCode = MSP430CC::COND_LO; 341f0001f41SAnton Korobeynikov else if (CC == "hs" || CC == "c") 342f0001f41SAnton Korobeynikov CondCode = MSP430CC::COND_HS; 343f0001f41SAnton Korobeynikov else if (CC == "n") 344f0001f41SAnton Korobeynikov CondCode = MSP430CC::COND_N; 345f0001f41SAnton Korobeynikov else if (CC == "ge") 346f0001f41SAnton Korobeynikov CondCode = MSP430CC::COND_GE; 347f0001f41SAnton Korobeynikov else if (CC == "l") 348f0001f41SAnton Korobeynikov CondCode = MSP430CC::COND_L; 349f0001f41SAnton Korobeynikov else if (CC == "mp") 350f0001f41SAnton Korobeynikov CondCode = MSP430CC::COND_NONE; 351f0001f41SAnton Korobeynikov else 352f0001f41SAnton Korobeynikov return Error(NameLoc, "unknown instruction"); 353f0001f41SAnton Korobeynikov 354f0001f41SAnton Korobeynikov if (CondCode == (unsigned)MSP430CC::COND_NONE) 355f0001f41SAnton Korobeynikov Operands.push_back(MSP430Operand::CreateToken("jmp", NameLoc)); 356f0001f41SAnton Korobeynikov else { 357f0001f41SAnton Korobeynikov Operands.push_back(MSP430Operand::CreateToken("j", NameLoc)); 358f0001f41SAnton Korobeynikov const MCExpr *CCode = MCConstantExpr::create(CondCode, getContext()); 359f0001f41SAnton Korobeynikov Operands.push_back(MSP430Operand::CreateImm(CCode, SMLoc(), SMLoc())); 360f0001f41SAnton Korobeynikov } 361f0001f41SAnton Korobeynikov 362f0001f41SAnton Korobeynikov // Skip optional '$' sign. 363f0001f41SAnton Korobeynikov if (getLexer().getKind() == AsmToken::Dollar) 364f0001f41SAnton Korobeynikov getLexer().Lex(); // Eat '$' 365f0001f41SAnton Korobeynikov 366f0001f41SAnton Korobeynikov const MCExpr *Val; 367f0001f41SAnton Korobeynikov SMLoc ExprLoc = getLexer().getLoc(); 368f0001f41SAnton Korobeynikov if (getParser().parseExpression(Val)) 369f0001f41SAnton Korobeynikov return Error(ExprLoc, "expected expression operand"); 370f0001f41SAnton Korobeynikov 371f0001f41SAnton Korobeynikov int64_t Res; 372f0001f41SAnton Korobeynikov if (Val->evaluateAsAbsolute(Res)) 373f0001f41SAnton Korobeynikov if (Res < -512 || Res > 511) 374f0001f41SAnton Korobeynikov return Error(ExprLoc, "invalid jump offset"); 375f0001f41SAnton Korobeynikov 376f0001f41SAnton Korobeynikov Operands.push_back(MSP430Operand::CreateImm(Val, ExprLoc, 377f0001f41SAnton Korobeynikov getLexer().getLoc())); 378f0001f41SAnton Korobeynikov 379f0001f41SAnton Korobeynikov if (getLexer().isNot(AsmToken::EndOfStatement)) { 380f0001f41SAnton Korobeynikov SMLoc Loc = getLexer().getLoc(); 381f0001f41SAnton Korobeynikov getParser().eatToEndOfStatement(); 382f0001f41SAnton Korobeynikov return Error(Loc, "unexpected token"); 383f0001f41SAnton Korobeynikov } 384f0001f41SAnton Korobeynikov 385f0001f41SAnton Korobeynikov getParser().Lex(); // Consume the EndOfStatement. 386f0001f41SAnton Korobeynikov return false; 387f0001f41SAnton Korobeynikov } 388f0001f41SAnton Korobeynikov 389f0001f41SAnton Korobeynikov bool MSP430AsmParser::ParseInstruction(ParseInstructionInfo &Info, 390f0001f41SAnton Korobeynikov StringRef Name, SMLoc NameLoc, 391f0001f41SAnton Korobeynikov OperandVector &Operands) { 392f0001f41SAnton Korobeynikov // Drop .w suffix 39342f74e82SMartin Storsjö if (Name.endswith_insensitive(".w")) 394f0001f41SAnton Korobeynikov Name = Name.drop_back(2); 395f0001f41SAnton Korobeynikov 396f0001f41SAnton Korobeynikov if (!parseJccInstruction(Info, Name, NameLoc, Operands)) 397f0001f41SAnton Korobeynikov return false; 398f0001f41SAnton Korobeynikov 399f0001f41SAnton Korobeynikov // First operand is instruction mnemonic 400f0001f41SAnton Korobeynikov Operands.push_back(MSP430Operand::CreateToken(Name, NameLoc)); 401f0001f41SAnton Korobeynikov 402f0001f41SAnton Korobeynikov // If there are no more operands, then finish 403f0001f41SAnton Korobeynikov if (getLexer().is(AsmToken::EndOfStatement)) 404f0001f41SAnton Korobeynikov return false; 405f0001f41SAnton Korobeynikov 406f0001f41SAnton Korobeynikov // Parse first operand 407f0001f41SAnton Korobeynikov if (ParseOperand(Operands)) 408f0001f41SAnton Korobeynikov return true; 409f0001f41SAnton Korobeynikov 410f0001f41SAnton Korobeynikov // Parse second operand if any 411f0001f41SAnton Korobeynikov if (getLexer().is(AsmToken::Comma)) { 412f0001f41SAnton Korobeynikov getLexer().Lex(); // Eat ',' 413f0001f41SAnton Korobeynikov if (ParseOperand(Operands)) 414f0001f41SAnton Korobeynikov return true; 415f0001f41SAnton Korobeynikov } 416f0001f41SAnton Korobeynikov 417f0001f41SAnton Korobeynikov if (getLexer().isNot(AsmToken::EndOfStatement)) { 418f0001f41SAnton Korobeynikov SMLoc Loc = getLexer().getLoc(); 419f0001f41SAnton Korobeynikov getParser().eatToEndOfStatement(); 420f0001f41SAnton Korobeynikov return Error(Loc, "unexpected token"); 421f0001f41SAnton Korobeynikov } 422f0001f41SAnton Korobeynikov 423f0001f41SAnton Korobeynikov getParser().Lex(); // Consume the EndOfStatement. 424f0001f41SAnton Korobeynikov return false; 425f0001f41SAnton Korobeynikov } 426f0001f41SAnton Korobeynikov 427411773d2SAnton Korobeynikov bool MSP430AsmParser::ParseDirectiveRefSym(AsmToken DirectiveID) { 428411773d2SAnton Korobeynikov StringRef Name; 429411773d2SAnton Korobeynikov if (getParser().parseIdentifier(Name)) 430411773d2SAnton Korobeynikov return TokError("expected identifier in directive"); 431411773d2SAnton Korobeynikov 432411773d2SAnton Korobeynikov MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 433a55daa14SFangrui Song getStreamer().emitSymbolAttribute(Sym, MCSA_Global); 434411773d2SAnton Korobeynikov return false; 435411773d2SAnton Korobeynikov } 436411773d2SAnton Korobeynikov 437f0001f41SAnton Korobeynikov bool MSP430AsmParser::ParseDirective(AsmToken DirectiveID) { 438f0001f41SAnton Korobeynikov StringRef IDVal = DirectiveID.getIdentifier(); 439f0001f41SAnton Korobeynikov if (IDVal.lower() == ".long") { 440f0001f41SAnton Korobeynikov ParseLiteralValues(4, DirectiveID.getLoc()); 441f0001f41SAnton Korobeynikov } else if (IDVal.lower() == ".word" || IDVal.lower() == ".short") { 442f0001f41SAnton Korobeynikov ParseLiteralValues(2, DirectiveID.getLoc()); 443f0001f41SAnton Korobeynikov } else if (IDVal.lower() == ".byte") { 444f0001f41SAnton Korobeynikov ParseLiteralValues(1, DirectiveID.getLoc()); 445411773d2SAnton Korobeynikov } else if (IDVal.lower() == ".refsym") { 446411773d2SAnton Korobeynikov return ParseDirectiveRefSym(DirectiveID); 447f0001f41SAnton Korobeynikov } 448f0001f41SAnton Korobeynikov return true; 449f0001f41SAnton Korobeynikov } 450f0001f41SAnton Korobeynikov 451f0001f41SAnton Korobeynikov bool MSP430AsmParser::ParseOperand(OperandVector &Operands) { 452f0001f41SAnton Korobeynikov switch (getLexer().getKind()) { 453f0001f41SAnton Korobeynikov default: return true; 454f0001f41SAnton Korobeynikov case AsmToken::Identifier: { 455f0001f41SAnton Korobeynikov // try rN 456f0001f41SAnton Korobeynikov unsigned RegNo; 457f0001f41SAnton Korobeynikov SMLoc StartLoc, EndLoc; 458f0001f41SAnton Korobeynikov if (!ParseRegister(RegNo, StartLoc, EndLoc)) { 459f0001f41SAnton Korobeynikov Operands.push_back(MSP430Operand::CreateReg(RegNo, StartLoc, EndLoc)); 460f0001f41SAnton Korobeynikov return false; 461f0001f41SAnton Korobeynikov } 462f0001f41SAnton Korobeynikov LLVM_FALLTHROUGH; 463f0001f41SAnton Korobeynikov } 464f0001f41SAnton Korobeynikov case AsmToken::Integer: 465f0001f41SAnton Korobeynikov case AsmToken::Plus: 466f0001f41SAnton Korobeynikov case AsmToken::Minus: { 467f0001f41SAnton Korobeynikov SMLoc StartLoc = getParser().getTok().getLoc(); 468f0001f41SAnton Korobeynikov const MCExpr *Val; 469f0001f41SAnton Korobeynikov // Try constexpr[(rN)] 470f0001f41SAnton Korobeynikov if (!getParser().parseExpression(Val)) { 471f0001f41SAnton Korobeynikov unsigned RegNo = MSP430::PC; 472f0001f41SAnton Korobeynikov SMLoc EndLoc = getParser().getTok().getLoc(); 473f0001f41SAnton Korobeynikov // Try (rN) 474f0001f41SAnton Korobeynikov if (getLexer().getKind() == AsmToken::LParen) { 475f0001f41SAnton Korobeynikov getLexer().Lex(); // Eat '(' 476f0001f41SAnton Korobeynikov SMLoc RegStartLoc; 477f0001f41SAnton Korobeynikov if (ParseRegister(RegNo, RegStartLoc, EndLoc)) 478f0001f41SAnton Korobeynikov return true; 479f0001f41SAnton Korobeynikov if (getLexer().getKind() != AsmToken::RParen) 480f0001f41SAnton Korobeynikov return true; 481f0001f41SAnton Korobeynikov EndLoc = getParser().getTok().getEndLoc(); 482f0001f41SAnton Korobeynikov getLexer().Lex(); // Eat ')' 483f0001f41SAnton Korobeynikov } 484f0001f41SAnton Korobeynikov Operands.push_back(MSP430Operand::CreateMem(RegNo, Val, StartLoc, 485f0001f41SAnton Korobeynikov EndLoc)); 486f0001f41SAnton Korobeynikov return false; 487f0001f41SAnton Korobeynikov } 488f0001f41SAnton Korobeynikov return true; 489f0001f41SAnton Korobeynikov } 490f0001f41SAnton Korobeynikov case AsmToken::Amp: { 491f0001f41SAnton Korobeynikov // Try &constexpr 492f0001f41SAnton Korobeynikov SMLoc StartLoc = getParser().getTok().getLoc(); 493f0001f41SAnton Korobeynikov getLexer().Lex(); // Eat '&' 494f0001f41SAnton Korobeynikov const MCExpr *Val; 495f0001f41SAnton Korobeynikov if (!getParser().parseExpression(Val)) { 496f0001f41SAnton Korobeynikov SMLoc EndLoc = getParser().getTok().getLoc(); 497f0001f41SAnton Korobeynikov Operands.push_back(MSP430Operand::CreateMem(MSP430::SR, Val, StartLoc, 498f0001f41SAnton Korobeynikov EndLoc)); 499f0001f41SAnton Korobeynikov return false; 500f0001f41SAnton Korobeynikov } 501f0001f41SAnton Korobeynikov return true; 502f0001f41SAnton Korobeynikov } 503f0001f41SAnton Korobeynikov case AsmToken::At: { 504f0001f41SAnton Korobeynikov // Try @rN[+] 505f0001f41SAnton Korobeynikov SMLoc StartLoc = getParser().getTok().getLoc(); 506f0001f41SAnton Korobeynikov getLexer().Lex(); // Eat '@' 507f0001f41SAnton Korobeynikov unsigned RegNo; 508f0001f41SAnton Korobeynikov SMLoc RegStartLoc, EndLoc; 509f0001f41SAnton Korobeynikov if (ParseRegister(RegNo, RegStartLoc, EndLoc)) 510f0001f41SAnton Korobeynikov return true; 511f0001f41SAnton Korobeynikov if (getLexer().getKind() == AsmToken::Plus) { 512f0001f41SAnton Korobeynikov Operands.push_back(MSP430Operand::CreatePostIndReg(RegNo, StartLoc, EndLoc)); 513f0001f41SAnton Korobeynikov getLexer().Lex(); // Eat '+' 514f0001f41SAnton Korobeynikov return false; 515f0001f41SAnton Korobeynikov } 5160681d6bcSAnton Korobeynikov if (Operands.size() > 1) // Emulate @rd in destination position as 0(rd) 5170681d6bcSAnton Korobeynikov Operands.push_back(MSP430Operand::CreateMem(RegNo, 5180681d6bcSAnton Korobeynikov MCConstantExpr::create(0, getContext()), StartLoc, EndLoc)); 5190681d6bcSAnton Korobeynikov else 520f0001f41SAnton Korobeynikov Operands.push_back(MSP430Operand::CreateIndReg(RegNo, StartLoc, EndLoc)); 521f0001f41SAnton Korobeynikov return false; 522f0001f41SAnton Korobeynikov } 523f0001f41SAnton Korobeynikov case AsmToken::Hash: 524f0001f41SAnton Korobeynikov // Try #constexpr 525f0001f41SAnton Korobeynikov SMLoc StartLoc = getParser().getTok().getLoc(); 526f0001f41SAnton Korobeynikov getLexer().Lex(); // Eat '#' 527f0001f41SAnton Korobeynikov const MCExpr *Val; 528f0001f41SAnton Korobeynikov if (!getParser().parseExpression(Val)) { 529f0001f41SAnton Korobeynikov SMLoc EndLoc = getParser().getTok().getLoc(); 530f0001f41SAnton Korobeynikov Operands.push_back(MSP430Operand::CreateImm(Val, StartLoc, EndLoc)); 531f0001f41SAnton Korobeynikov return false; 532f0001f41SAnton Korobeynikov } 533f0001f41SAnton Korobeynikov return true; 534f0001f41SAnton Korobeynikov } 535f0001f41SAnton Korobeynikov } 536f0001f41SAnton Korobeynikov 537f0001f41SAnton Korobeynikov bool MSP430AsmParser::ParseLiteralValues(unsigned Size, SMLoc L) { 538f0001f41SAnton Korobeynikov auto parseOne = [&]() -> bool { 539f0001f41SAnton Korobeynikov const MCExpr *Value; 540f0001f41SAnton Korobeynikov if (getParser().parseExpression(Value)) 541f0001f41SAnton Korobeynikov return true; 54277497103SFangrui Song getParser().getStreamer().emitValue(Value, Size, L); 543f0001f41SAnton Korobeynikov return false; 544f0001f41SAnton Korobeynikov }; 545f0001f41SAnton Korobeynikov return (parseMany(parseOne)); 546f0001f41SAnton Korobeynikov } 547f0001f41SAnton Korobeynikov 5480dbcb363STom Stellard extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMSP430AsmParser() { 549f0001f41SAnton Korobeynikov RegisterMCAsmParser<MSP430AsmParser> X(getTheMSP430Target()); 550f0001f41SAnton Korobeynikov } 551f0001f41SAnton Korobeynikov 552f0001f41SAnton Korobeynikov #define GET_REGISTER_MATCHER 553f0001f41SAnton Korobeynikov #define GET_MATCHER_IMPLEMENTATION 554f0001f41SAnton Korobeynikov #include "MSP430GenAsmMatcher.inc" 555f0001f41SAnton Korobeynikov 556f0001f41SAnton Korobeynikov static unsigned convertGR16ToGR8(unsigned Reg) { 557f0001f41SAnton Korobeynikov switch (Reg) { 558f0001f41SAnton Korobeynikov default: 559f0001f41SAnton Korobeynikov llvm_unreachable("Unknown GR16 register"); 560f0001f41SAnton Korobeynikov case MSP430::PC: return MSP430::PCB; 561f0001f41SAnton Korobeynikov case MSP430::SP: return MSP430::SPB; 562f0001f41SAnton Korobeynikov case MSP430::SR: return MSP430::SRB; 563f0001f41SAnton Korobeynikov case MSP430::CG: return MSP430::CGB; 564cb56fa21SAnatoly Trosinenko case MSP430::R4: return MSP430::R4B; 565f0001f41SAnton Korobeynikov case MSP430::R5: return MSP430::R5B; 566f0001f41SAnton Korobeynikov case MSP430::R6: return MSP430::R6B; 567f0001f41SAnton Korobeynikov case MSP430::R7: return MSP430::R7B; 568f0001f41SAnton Korobeynikov case MSP430::R8: return MSP430::R8B; 569f0001f41SAnton Korobeynikov case MSP430::R9: return MSP430::R9B; 570f0001f41SAnton Korobeynikov case MSP430::R10: return MSP430::R10B; 571f0001f41SAnton Korobeynikov case MSP430::R11: return MSP430::R11B; 572f0001f41SAnton Korobeynikov case MSP430::R12: return MSP430::R12B; 573f0001f41SAnton Korobeynikov case MSP430::R13: return MSP430::R13B; 574f0001f41SAnton Korobeynikov case MSP430::R14: return MSP430::R14B; 575f0001f41SAnton Korobeynikov case MSP430::R15: return MSP430::R15B; 576f0001f41SAnton Korobeynikov } 577f0001f41SAnton Korobeynikov } 578f0001f41SAnton Korobeynikov 579f0001f41SAnton Korobeynikov unsigned MSP430AsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, 580f0001f41SAnton Korobeynikov unsigned Kind) { 581f0001f41SAnton Korobeynikov MSP430Operand &Op = static_cast<MSP430Operand &>(AsmOp); 582f0001f41SAnton Korobeynikov 583f0001f41SAnton Korobeynikov if (!Op.isReg()) 584f0001f41SAnton Korobeynikov return Match_InvalidOperand; 585f0001f41SAnton Korobeynikov 586f0001f41SAnton Korobeynikov unsigned Reg = Op.getReg(); 587f0001f41SAnton Korobeynikov bool isGR16 = 588f0001f41SAnton Korobeynikov MSP430MCRegisterClasses[MSP430::GR16RegClassID].contains(Reg); 589f0001f41SAnton Korobeynikov 590f0001f41SAnton Korobeynikov if (isGR16 && (Kind == MCK_GR8)) { 591f0001f41SAnton Korobeynikov Op.setReg(convertGR16ToGR8(Reg)); 592f0001f41SAnton Korobeynikov return Match_Success; 593f0001f41SAnton Korobeynikov } 594f0001f41SAnton Korobeynikov 595f0001f41SAnton Korobeynikov return Match_InvalidOperand; 596f0001f41SAnton Korobeynikov } 597