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