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