10b57cec5SDimitry Andric //===---- AVRAsmParser.cpp - Parse AVR assembly to MCInst instructions ----===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "AVR.h" 100b57cec5SDimitry Andric #include "AVRRegisterInfo.h" 110b57cec5SDimitry Andric #include "MCTargetDesc/AVRMCELFStreamer.h" 120b57cec5SDimitry Andric #include "MCTargetDesc/AVRMCExpr.h" 130b57cec5SDimitry Andric #include "MCTargetDesc/AVRMCTargetDesc.h" 140b57cec5SDimitry Andric #include "TargetInfo/AVRTargetInfo.h" 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "llvm/ADT/APInt.h" 170b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 180b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h" 190b57cec5SDimitry Andric #include "llvm/MC/MCInst.h" 200b57cec5SDimitry Andric #include "llvm/MC/MCInstBuilder.h" 210b57cec5SDimitry Andric #include "llvm/MC/MCParser/MCAsmLexer.h" 220b57cec5SDimitry Andric #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 230b57cec5SDimitry Andric #include "llvm/MC/MCParser/MCTargetAsmParser.h" 240b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 250b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h" 260b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h" 270b57cec5SDimitry Andric #include "llvm/MC/MCValue.h" 28349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h" 290b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 300b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h" 310b57cec5SDimitry Andric 32bdd1243dSDimitry Andric #include <array> 330b57cec5SDimitry Andric #include <sstream> 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric #define DEBUG_TYPE "avr-asm-parser" 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric using namespace llvm; 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric namespace { 400b57cec5SDimitry Andric /// Parses AVR assembly from a stream. 410b57cec5SDimitry Andric class AVRAsmParser : public MCTargetAsmParser { 420b57cec5SDimitry Andric const MCSubtargetInfo &STI; 430b57cec5SDimitry Andric MCAsmParser &Parser; 440b57cec5SDimitry Andric const MCRegisterInfo *MRI; 450b57cec5SDimitry Andric const std::string GENERATE_STUBS = "gs"; 460b57cec5SDimitry Andric 4781ad6265SDimitry Andric enum AVRMatchResultTy { 4881ad6265SDimitry Andric Match_InvalidRegisterOnTiny = FIRST_TARGET_MATCH_RESULT_TY + 1, 4981ad6265SDimitry Andric }; 5081ad6265SDimitry Andric 510b57cec5SDimitry Andric #define GET_ASSEMBLER_HEADER 520b57cec5SDimitry Andric #include "AVRGenAsmMatcher.inc" 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 550b57cec5SDimitry Andric OperandVector &Operands, MCStreamer &Out, 560b57cec5SDimitry Andric uint64_t &ErrorInfo, 570b57cec5SDimitry Andric bool MatchingInlineAsm) override; 580b57cec5SDimitry Andric 595f757f3fSDimitry Andric bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override; 605f757f3fSDimitry Andric ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, 615ffd83dbSDimitry Andric SMLoc &EndLoc) override; 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 640b57cec5SDimitry Andric SMLoc NameLoc, OperandVector &Operands) override; 650b57cec5SDimitry Andric 6606c3fb27SDimitry Andric ParseStatus parseDirective(AsmToken DirectiveID) override; 670b57cec5SDimitry Andric 685f757f3fSDimitry Andric ParseStatus parseMemriOperand(OperandVector &Operands); 690b57cec5SDimitry Andric 70bdd1243dSDimitry Andric bool parseOperand(OperandVector &Operands, bool maybeReg); 710fca6ea1SDimitry Andric int parseRegisterName(MCRegister (*matchFn)(StringRef)); 720b57cec5SDimitry Andric int parseRegisterName(); 735ffd83dbSDimitry Andric int parseRegister(bool RestoreOnFailure = false); 740b57cec5SDimitry Andric bool tryParseRegisterOperand(OperandVector &Operands); 75*6c4b055cSDimitry Andric bool tryParseExpression(OperandVector &Operands, int64_t offset); 760b57cec5SDimitry Andric bool tryParseRelocExpression(OperandVector &Operands); 770b57cec5SDimitry Andric void eatComma(); 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, 800b57cec5SDimitry Andric unsigned Kind) override; 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric unsigned toDREG(unsigned Reg, unsigned From = AVR::sub_lo) { 830b57cec5SDimitry Andric MCRegisterClass const *Class = &AVRMCRegisterClasses[AVR::DREGSRegClassID]; 840b57cec5SDimitry Andric return MRI->getMatchingSuperReg(Reg, From, Class); 850b57cec5SDimitry Andric } 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric bool emit(MCInst &Instruction, SMLoc const &Loc, MCStreamer &Out) const; 880b57cec5SDimitry Andric bool invalidOperand(SMLoc const &Loc, OperandVector const &Operands, 890b57cec5SDimitry Andric uint64_t const &ErrorInfo); 900b57cec5SDimitry Andric bool missingFeature(SMLoc const &Loc, uint64_t const &ErrorInfo); 910b57cec5SDimitry Andric 9206c3fb27SDimitry Andric ParseStatus parseLiteralValues(unsigned SizeInBytes, SMLoc L); 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric public: 950b57cec5SDimitry Andric AVRAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, 960b57cec5SDimitry Andric const MCInstrInfo &MII, const MCTargetOptions &Options) 970b57cec5SDimitry Andric : MCTargetAsmParser(Options, STI, MII), STI(STI), Parser(Parser) { 980b57cec5SDimitry Andric MCAsmParserExtension::Initialize(Parser); 990b57cec5SDimitry Andric MRI = getContext().getRegisterInfo(); 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 1020b57cec5SDimitry Andric } 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric MCAsmParser &getParser() const { return Parser; } 1050b57cec5SDimitry Andric MCAsmLexer &getLexer() const { return Parser.getLexer(); } 1060b57cec5SDimitry Andric }; 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric /// An parsed AVR assembly operand. 1090b57cec5SDimitry Andric class AVROperand : public MCParsedAsmOperand { 1100b57cec5SDimitry Andric typedef MCParsedAsmOperand Base; 1110b57cec5SDimitry Andric enum KindTy { k_Immediate, k_Register, k_Token, k_Memri } Kind; 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric public: 1140b57cec5SDimitry Andric AVROperand(StringRef Tok, SMLoc const &S) 11504eeddc0SDimitry Andric : Kind(k_Token), Tok(Tok), Start(S), End(S) {} 1160b57cec5SDimitry Andric AVROperand(unsigned Reg, SMLoc const &S, SMLoc const &E) 11704eeddc0SDimitry Andric : Kind(k_Register), RegImm({Reg, nullptr}), Start(S), End(E) {} 1180b57cec5SDimitry Andric AVROperand(MCExpr const *Imm, SMLoc const &S, SMLoc const &E) 11904eeddc0SDimitry Andric : Kind(k_Immediate), RegImm({0, Imm}), Start(S), End(E) {} 1200b57cec5SDimitry Andric AVROperand(unsigned Reg, MCExpr const *Imm, SMLoc const &S, SMLoc const &E) 12104eeddc0SDimitry Andric : Kind(k_Memri), RegImm({Reg, Imm}), Start(S), End(E) {} 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric struct RegisterImmediate { 1240b57cec5SDimitry Andric unsigned Reg; 1250b57cec5SDimitry Andric MCExpr const *Imm; 1260b57cec5SDimitry Andric }; 1270b57cec5SDimitry Andric union { 1280b57cec5SDimitry Andric StringRef Tok; 1290b57cec5SDimitry Andric RegisterImmediate RegImm; 1300b57cec5SDimitry Andric }; 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric SMLoc Start, End; 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric public: 1350b57cec5SDimitry Andric void addRegOperands(MCInst &Inst, unsigned N) const { 1360b57cec5SDimitry Andric assert(Kind == k_Register && "Unexpected operand kind"); 1370b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!"); 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric Inst.addOperand(MCOperand::createReg(getReg())); 1400b57cec5SDimitry Andric } 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric void addExpr(MCInst &Inst, const MCExpr *Expr) const { 1430b57cec5SDimitry Andric // Add as immediate when possible 1440b57cec5SDimitry Andric if (!Expr) 1450b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(0)); 1460b57cec5SDimitry Andric else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 1470b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(CE->getValue())); 1480b57cec5SDimitry Andric else 1490b57cec5SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr)); 1500b57cec5SDimitry Andric } 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric void addImmOperands(MCInst &Inst, unsigned N) const { 1530b57cec5SDimitry Andric assert(Kind == k_Immediate && "Unexpected operand kind"); 1540b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!"); 1550b57cec5SDimitry Andric 1560b57cec5SDimitry Andric const MCExpr *Expr = getImm(); 1570b57cec5SDimitry Andric addExpr(Inst, Expr); 1580b57cec5SDimitry Andric } 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric /// Adds the contained reg+imm operand to an instruction. 1610b57cec5SDimitry Andric void addMemriOperands(MCInst &Inst, unsigned N) const { 1620b57cec5SDimitry Andric assert(Kind == k_Memri && "Unexpected operand kind"); 1630b57cec5SDimitry Andric assert(N == 2 && "Invalid number of operands"); 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric Inst.addOperand(MCOperand::createReg(getReg())); 1660b57cec5SDimitry Andric addExpr(Inst, getImm()); 1670b57cec5SDimitry Andric } 1680b57cec5SDimitry Andric 1690b57cec5SDimitry Andric void addImmCom8Operands(MCInst &Inst, unsigned N) const { 1700b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!"); 1710b57cec5SDimitry Andric // The operand is actually a imm8, but we have its bitwise 1720b57cec5SDimitry Andric // negation in the assembly source, so twiddle it here. 173e8d8bef9SDimitry Andric const auto *CE = cast<MCConstantExpr>(getImm()); 1740b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(~(uint8_t)CE->getValue())); 1750b57cec5SDimitry Andric } 1760b57cec5SDimitry Andric 1770b57cec5SDimitry Andric bool isImmCom8() const { 178349cc55cSDimitry Andric if (!isImm()) 179349cc55cSDimitry Andric return false; 180e8d8bef9SDimitry Andric const auto *CE = dyn_cast<MCConstantExpr>(getImm()); 181349cc55cSDimitry Andric if (!CE) 182349cc55cSDimitry Andric return false; 1830b57cec5SDimitry Andric int64_t Value = CE->getValue(); 1840b57cec5SDimitry Andric return isUInt<8>(Value); 1850b57cec5SDimitry Andric } 1860b57cec5SDimitry Andric 1875ffd83dbSDimitry Andric bool isReg() const override { return Kind == k_Register; } 1885ffd83dbSDimitry Andric bool isImm() const override { return Kind == k_Immediate; } 1895ffd83dbSDimitry Andric bool isToken() const override { return Kind == k_Token; } 1905ffd83dbSDimitry Andric bool isMem() const override { return Kind == k_Memri; } 1910b57cec5SDimitry Andric bool isMemri() const { return Kind == k_Memri; } 1920b57cec5SDimitry Andric 1930b57cec5SDimitry Andric StringRef getToken() const { 1940b57cec5SDimitry Andric assert(Kind == k_Token && "Invalid access!"); 1950b57cec5SDimitry Andric return Tok; 1960b57cec5SDimitry Andric } 1970b57cec5SDimitry Andric 1980fca6ea1SDimitry Andric MCRegister getReg() const override { 1990b57cec5SDimitry Andric assert((Kind == k_Register || Kind == k_Memri) && "Invalid access!"); 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric return RegImm.Reg; 2020b57cec5SDimitry Andric } 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric const MCExpr *getImm() const { 2050b57cec5SDimitry Andric assert((Kind == k_Immediate || Kind == k_Memri) && "Invalid access!"); 2060b57cec5SDimitry Andric return RegImm.Imm; 2070b57cec5SDimitry Andric } 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric static std::unique_ptr<AVROperand> CreateToken(StringRef Str, SMLoc S) { 2108bcb0991SDimitry Andric return std::make_unique<AVROperand>(Str, S); 2110b57cec5SDimitry Andric } 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric static std::unique_ptr<AVROperand> CreateReg(unsigned RegNum, SMLoc S, 2140b57cec5SDimitry Andric SMLoc E) { 2158bcb0991SDimitry Andric return std::make_unique<AVROperand>(RegNum, S, E); 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric static std::unique_ptr<AVROperand> CreateImm(const MCExpr *Val, SMLoc S, 2190b57cec5SDimitry Andric SMLoc E) { 2208bcb0991SDimitry Andric return std::make_unique<AVROperand>(Val, S, E); 2210b57cec5SDimitry Andric } 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric static std::unique_ptr<AVROperand> 2240b57cec5SDimitry Andric CreateMemri(unsigned RegNum, const MCExpr *Val, SMLoc S, SMLoc E) { 2258bcb0991SDimitry Andric return std::make_unique<AVROperand>(RegNum, Val, S, E); 2260b57cec5SDimitry Andric } 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric void makeToken(StringRef Token) { 2290b57cec5SDimitry Andric Kind = k_Token; 2300b57cec5SDimitry Andric Tok = Token; 2310b57cec5SDimitry Andric } 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andric void makeReg(unsigned RegNo) { 2340b57cec5SDimitry Andric Kind = k_Register; 2350b57cec5SDimitry Andric RegImm = {RegNo, nullptr}; 2360b57cec5SDimitry Andric } 2370b57cec5SDimitry Andric 2380b57cec5SDimitry Andric void makeImm(MCExpr const *Ex) { 2390b57cec5SDimitry Andric Kind = k_Immediate; 2400b57cec5SDimitry Andric RegImm = {0, Ex}; 2410b57cec5SDimitry Andric } 2420b57cec5SDimitry Andric 2430b57cec5SDimitry Andric void makeMemri(unsigned RegNo, MCExpr const *Imm) { 2440b57cec5SDimitry Andric Kind = k_Memri; 2450b57cec5SDimitry Andric RegImm = {RegNo, Imm}; 2460b57cec5SDimitry Andric } 2470b57cec5SDimitry Andric 2485ffd83dbSDimitry Andric SMLoc getStartLoc() const override { return Start; } 2495ffd83dbSDimitry Andric SMLoc getEndLoc() const override { return End; } 2500b57cec5SDimitry Andric 2515ffd83dbSDimitry Andric void print(raw_ostream &O) const override { 2520b57cec5SDimitry Andric switch (Kind) { 2530b57cec5SDimitry Andric case k_Token: 2540b57cec5SDimitry Andric O << "Token: \"" << getToken() << "\""; 2550b57cec5SDimitry Andric break; 2560b57cec5SDimitry Andric case k_Register: 2570b57cec5SDimitry Andric O << "Register: " << getReg(); 2580b57cec5SDimitry Andric break; 2590b57cec5SDimitry Andric case k_Immediate: 2600b57cec5SDimitry Andric O << "Immediate: \"" << *getImm() << "\""; 2610b57cec5SDimitry Andric break; 2620b57cec5SDimitry Andric case k_Memri: { 2630b57cec5SDimitry Andric // only manually print the size for non-negative values, 2640b57cec5SDimitry Andric // as the sign is inserted automatically. 2650b57cec5SDimitry Andric O << "Memri: \"" << getReg() << '+' << *getImm() << "\""; 2660b57cec5SDimitry Andric break; 2670b57cec5SDimitry Andric } 2680b57cec5SDimitry Andric } 2690b57cec5SDimitry Andric O << "\n"; 2700b57cec5SDimitry Andric } 2710b57cec5SDimitry Andric }; 2720b57cec5SDimitry Andric 2730b57cec5SDimitry Andric } // end anonymous namespace. 2740b57cec5SDimitry Andric 2750b57cec5SDimitry Andric // Auto-generated Match Functions 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric /// Maps from the set of all register names to a register number. 2780b57cec5SDimitry Andric /// \note Generated by TableGen. 2790fca6ea1SDimitry Andric static MCRegister MatchRegisterName(StringRef Name); 2800b57cec5SDimitry Andric 2810b57cec5SDimitry Andric /// Maps from the set of all alternative registernames to a register number. 2820b57cec5SDimitry Andric /// \note Generated by TableGen. 2830fca6ea1SDimitry Andric static MCRegister MatchRegisterAltName(StringRef Name); 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric bool AVRAsmParser::invalidOperand(SMLoc const &Loc, 2860b57cec5SDimitry Andric OperandVector const &Operands, 2870b57cec5SDimitry Andric uint64_t const &ErrorInfo) { 2880b57cec5SDimitry Andric SMLoc ErrorLoc = Loc; 28904eeddc0SDimitry Andric char const *Diag = nullptr; 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andric if (ErrorInfo != ~0U) { 2920b57cec5SDimitry Andric if (ErrorInfo >= Operands.size()) { 2930b57cec5SDimitry Andric Diag = "too few operands for instruction."; 2940b57cec5SDimitry Andric } else { 2950b57cec5SDimitry Andric AVROperand const &Op = (AVROperand const &)*Operands[ErrorInfo]; 2960b57cec5SDimitry Andric 2970b57cec5SDimitry Andric // TODO: See if we can do a better error than just "invalid ...". 2980b57cec5SDimitry Andric if (Op.getStartLoc() != SMLoc()) { 2990b57cec5SDimitry Andric ErrorLoc = Op.getStartLoc(); 3000b57cec5SDimitry Andric } 3010b57cec5SDimitry Andric } 3020b57cec5SDimitry Andric } 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric if (!Diag) { 3050b57cec5SDimitry Andric Diag = "invalid operand for instruction"; 3060b57cec5SDimitry Andric } 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andric return Error(ErrorLoc, Diag); 3090b57cec5SDimitry Andric } 3100b57cec5SDimitry Andric 3110b57cec5SDimitry Andric bool AVRAsmParser::missingFeature(llvm::SMLoc const &Loc, 3120b57cec5SDimitry Andric uint64_t const &ErrorInfo) { 3130b57cec5SDimitry Andric return Error(Loc, "instruction requires a CPU feature not currently enabled"); 3140b57cec5SDimitry Andric } 3150b57cec5SDimitry Andric 3160b57cec5SDimitry Andric bool AVRAsmParser::emit(MCInst &Inst, SMLoc const &Loc, MCStreamer &Out) const { 3170b57cec5SDimitry Andric Inst.setLoc(Loc); 3185ffd83dbSDimitry Andric Out.emitInstruction(Inst, STI); 3190b57cec5SDimitry Andric 3200b57cec5SDimitry Andric return false; 3210b57cec5SDimitry Andric } 3220b57cec5SDimitry Andric 3230b57cec5SDimitry Andric bool AVRAsmParser::MatchAndEmitInstruction(SMLoc Loc, unsigned &Opcode, 3240b57cec5SDimitry Andric OperandVector &Operands, 3250b57cec5SDimitry Andric MCStreamer &Out, uint64_t &ErrorInfo, 3260b57cec5SDimitry Andric bool MatchingInlineAsm) { 3270b57cec5SDimitry Andric MCInst Inst; 3280b57cec5SDimitry Andric unsigned MatchResult = 3290b57cec5SDimitry Andric MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); 3300b57cec5SDimitry Andric 3310b57cec5SDimitry Andric switch (MatchResult) { 332349cc55cSDimitry Andric case Match_Success: 333349cc55cSDimitry Andric return emit(Inst, Loc, Out); 334349cc55cSDimitry Andric case Match_MissingFeature: 335349cc55cSDimitry Andric return missingFeature(Loc, ErrorInfo); 336349cc55cSDimitry Andric case Match_InvalidOperand: 337349cc55cSDimitry Andric return invalidOperand(Loc, Operands, ErrorInfo); 338349cc55cSDimitry Andric case Match_MnemonicFail: 339349cc55cSDimitry Andric return Error(Loc, "invalid instruction"); 34081ad6265SDimitry Andric case Match_InvalidRegisterOnTiny: 34181ad6265SDimitry Andric return Error(Loc, "invalid register on avrtiny"); 342349cc55cSDimitry Andric default: 343349cc55cSDimitry Andric return true; 3440b57cec5SDimitry Andric } 3450b57cec5SDimitry Andric } 3460b57cec5SDimitry Andric 3470b57cec5SDimitry Andric /// Parses a register name using a given matching function. 3480b57cec5SDimitry Andric /// Checks for lowercase or uppercase if necessary. 3490fca6ea1SDimitry Andric int AVRAsmParser::parseRegisterName(MCRegister (*matchFn)(StringRef)) { 3500b57cec5SDimitry Andric StringRef Name = Parser.getTok().getString(); 3510b57cec5SDimitry Andric 3520b57cec5SDimitry Andric int RegNum = matchFn(Name); 3530b57cec5SDimitry Andric 3540b57cec5SDimitry Andric // GCC supports case insensitive register names. Some of the AVR registers 3550b57cec5SDimitry Andric // are all lower case, some are all upper case but non are mixed. We prefer 3560b57cec5SDimitry Andric // to use the original names in the register definitions. That is why we 3570b57cec5SDimitry Andric // have to test both upper and lower case here. 3580b57cec5SDimitry Andric if (RegNum == AVR::NoRegister) { 3590b57cec5SDimitry Andric RegNum = matchFn(Name.lower()); 3600b57cec5SDimitry Andric } 3610b57cec5SDimitry Andric if (RegNum == AVR::NoRegister) { 3620b57cec5SDimitry Andric RegNum = matchFn(Name.upper()); 3630b57cec5SDimitry Andric } 3640b57cec5SDimitry Andric 3650b57cec5SDimitry Andric return RegNum; 3660b57cec5SDimitry Andric } 3670b57cec5SDimitry Andric 3680b57cec5SDimitry Andric int AVRAsmParser::parseRegisterName() { 3690b57cec5SDimitry Andric int RegNum = parseRegisterName(&MatchRegisterName); 3700b57cec5SDimitry Andric 3710b57cec5SDimitry Andric if (RegNum == AVR::NoRegister) 3720b57cec5SDimitry Andric RegNum = parseRegisterName(&MatchRegisterAltName); 3730b57cec5SDimitry Andric 3740b57cec5SDimitry Andric return RegNum; 3750b57cec5SDimitry Andric } 3760b57cec5SDimitry Andric 3775ffd83dbSDimitry Andric int AVRAsmParser::parseRegister(bool RestoreOnFailure) { 3780b57cec5SDimitry Andric int RegNum = AVR::NoRegister; 3790b57cec5SDimitry Andric 3800b57cec5SDimitry Andric if (Parser.getTok().is(AsmToken::Identifier)) { 3810b57cec5SDimitry Andric // Check for register pair syntax 3820b57cec5SDimitry Andric if (Parser.getLexer().peekTok().is(AsmToken::Colon)) { 3835ffd83dbSDimitry Andric AsmToken HighTok = Parser.getTok(); 3840b57cec5SDimitry Andric Parser.Lex(); 3855ffd83dbSDimitry Andric AsmToken ColonTok = Parser.getTok(); 3860b57cec5SDimitry Andric Parser.Lex(); // Eat high (odd) register and colon 3870b57cec5SDimitry Andric 3880b57cec5SDimitry Andric if (Parser.getTok().is(AsmToken::Identifier)) { 3890b57cec5SDimitry Andric // Convert lower (even) register to DREG 3900b57cec5SDimitry Andric RegNum = toDREG(parseRegisterName()); 3910b57cec5SDimitry Andric } 3925ffd83dbSDimitry Andric if (RegNum == AVR::NoRegister && RestoreOnFailure) { 3935ffd83dbSDimitry Andric getLexer().UnLex(std::move(ColonTok)); 3945ffd83dbSDimitry Andric getLexer().UnLex(std::move(HighTok)); 3955ffd83dbSDimitry Andric } 3960b57cec5SDimitry Andric } else { 3970b57cec5SDimitry Andric RegNum = parseRegisterName(); 3980b57cec5SDimitry Andric } 3990b57cec5SDimitry Andric } 4000b57cec5SDimitry Andric return RegNum; 4010b57cec5SDimitry Andric } 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric bool AVRAsmParser::tryParseRegisterOperand(OperandVector &Operands) { 4040b57cec5SDimitry Andric int RegNo = parseRegister(); 4050b57cec5SDimitry Andric 4060b57cec5SDimitry Andric if (RegNo == AVR::NoRegister) 4070b57cec5SDimitry Andric return true; 4080b57cec5SDimitry Andric 40981ad6265SDimitry Andric // Reject R0~R15 on avrtiny. 41081ad6265SDimitry Andric if (AVR::R0 <= RegNo && RegNo <= AVR::R15 && 41181ad6265SDimitry Andric STI.hasFeature(AVR::FeatureTinyEncoding)) 41281ad6265SDimitry Andric return Error(Parser.getTok().getLoc(), "invalid register on avrtiny"); 41381ad6265SDimitry Andric 4140b57cec5SDimitry Andric AsmToken const &T = Parser.getTok(); 4150b57cec5SDimitry Andric Operands.push_back(AVROperand::CreateReg(RegNo, T.getLoc(), T.getEndLoc())); 4160b57cec5SDimitry Andric Parser.Lex(); // Eat register token. 4170b57cec5SDimitry Andric 4180b57cec5SDimitry Andric return false; 4190b57cec5SDimitry Andric } 4200b57cec5SDimitry Andric 421*6c4b055cSDimitry Andric bool AVRAsmParser::tryParseExpression(OperandVector &Operands, int64_t offset) { 4220b57cec5SDimitry Andric SMLoc S = Parser.getTok().getLoc(); 4230b57cec5SDimitry Andric 4240b57cec5SDimitry Andric if (!tryParseRelocExpression(Operands)) 4250b57cec5SDimitry Andric return false; 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andric if ((Parser.getTok().getKind() == AsmToken::Plus || 4280b57cec5SDimitry Andric Parser.getTok().getKind() == AsmToken::Minus) && 4290b57cec5SDimitry Andric Parser.getLexer().peekTok().getKind() == AsmToken::Identifier) { 4300b57cec5SDimitry Andric // Don't handle this case - it should be split into two 4310b57cec5SDimitry Andric // separate tokens. 4320b57cec5SDimitry Andric return true; 4330b57cec5SDimitry Andric } 4340b57cec5SDimitry Andric 4350b57cec5SDimitry Andric // Parse (potentially inner) expression 4360b57cec5SDimitry Andric MCExpr const *Expression; 4370b57cec5SDimitry Andric if (getParser().parseExpression(Expression)) 4380b57cec5SDimitry Andric return true; 4390b57cec5SDimitry Andric 440*6c4b055cSDimitry Andric if (offset) { 441*6c4b055cSDimitry Andric Expression = MCBinaryExpr::createAdd( 442*6c4b055cSDimitry Andric Expression, MCConstantExpr::create(offset, getContext()), getContext()); 443*6c4b055cSDimitry Andric } 444*6c4b055cSDimitry Andric 4450b57cec5SDimitry Andric SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 4460b57cec5SDimitry Andric Operands.push_back(AVROperand::CreateImm(Expression, S, E)); 4470b57cec5SDimitry Andric return false; 4480b57cec5SDimitry Andric } 4490b57cec5SDimitry Andric 4500b57cec5SDimitry Andric bool AVRAsmParser::tryParseRelocExpression(OperandVector &Operands) { 4510b57cec5SDimitry Andric bool isNegated = false; 4520b57cec5SDimitry Andric AVRMCExpr::VariantKind ModifierKind = AVRMCExpr::VK_AVR_None; 4530b57cec5SDimitry Andric 4540b57cec5SDimitry Andric SMLoc S = Parser.getTok().getLoc(); 4550b57cec5SDimitry Andric 456bdd1243dSDimitry Andric // Reject the form in which sign comes first. This behaviour is 457bdd1243dSDimitry Andric // in accordance with avr-gcc. 4580b57cec5SDimitry Andric AsmToken::TokenKind CurTok = Parser.getLexer().getKind(); 4590b57cec5SDimitry Andric if (CurTok == AsmToken::Minus || CurTok == AsmToken::Plus) 460bdd1243dSDimitry Andric return true; 461bdd1243dSDimitry Andric 462bdd1243dSDimitry Andric // Check for sign. 463bdd1243dSDimitry Andric AsmToken tokens[2]; 464bdd1243dSDimitry Andric if (Parser.getLexer().peekTokens(tokens) == 2) 465bdd1243dSDimitry Andric if (tokens[0].getKind() == AsmToken::LParen && 466bdd1243dSDimitry Andric tokens[1].getKind() == AsmToken::Minus) 467bdd1243dSDimitry Andric isNegated = true; 4680b57cec5SDimitry Andric 4690b57cec5SDimitry Andric // Check if we have a target specific modifier (lo8, hi8, &c) 470bdd1243dSDimitry Andric if (CurTok != AsmToken::Identifier || 4710b57cec5SDimitry Andric Parser.getLexer().peekTok().getKind() != AsmToken::LParen) { 4720b57cec5SDimitry Andric // Not a reloc expr 4730b57cec5SDimitry Andric return true; 4740b57cec5SDimitry Andric } 4750b57cec5SDimitry Andric StringRef ModifierName = Parser.getTok().getString(); 476349cc55cSDimitry Andric ModifierKind = AVRMCExpr::getKindByName(ModifierName); 4770b57cec5SDimitry Andric 4780b57cec5SDimitry Andric if (ModifierKind != AVRMCExpr::VK_AVR_None) { 4790b57cec5SDimitry Andric Parser.Lex(); 4800b57cec5SDimitry Andric Parser.Lex(); // Eat modifier name and parenthesis 4810b57cec5SDimitry Andric if (Parser.getTok().getString() == GENERATE_STUBS && 4820b57cec5SDimitry Andric Parser.getTok().getKind() == AsmToken::Identifier) { 4830b57cec5SDimitry Andric std::string GSModName = ModifierName.str() + "_" + GENERATE_STUBS; 484349cc55cSDimitry Andric ModifierKind = AVRMCExpr::getKindByName(GSModName); 4850b57cec5SDimitry Andric if (ModifierKind != AVRMCExpr::VK_AVR_None) 4860b57cec5SDimitry Andric Parser.Lex(); // Eat gs modifier name 4870b57cec5SDimitry Andric } 4880b57cec5SDimitry Andric } else { 4890b57cec5SDimitry Andric return Error(Parser.getTok().getLoc(), "unknown modifier"); 4900b57cec5SDimitry Andric } 4910b57cec5SDimitry Andric 4920b57cec5SDimitry Andric if (tokens[1].getKind() == AsmToken::Minus || 4930b57cec5SDimitry Andric tokens[1].getKind() == AsmToken::Plus) { 4940b57cec5SDimitry Andric Parser.Lex(); 4950b57cec5SDimitry Andric assert(Parser.getTok().getKind() == AsmToken::LParen); 4960b57cec5SDimitry Andric Parser.Lex(); // Eat the sign and parenthesis 4970b57cec5SDimitry Andric } 4980b57cec5SDimitry Andric 4990b57cec5SDimitry Andric MCExpr const *InnerExpression; 5000b57cec5SDimitry Andric if (getParser().parseExpression(InnerExpression)) 5010b57cec5SDimitry Andric return true; 5020b57cec5SDimitry Andric 5030b57cec5SDimitry Andric if (tokens[1].getKind() == AsmToken::Minus || 5040b57cec5SDimitry Andric tokens[1].getKind() == AsmToken::Plus) { 5050b57cec5SDimitry Andric assert(Parser.getTok().getKind() == AsmToken::RParen); 5060b57cec5SDimitry Andric Parser.Lex(); // Eat closing parenthesis 5070b57cec5SDimitry Andric } 5080b57cec5SDimitry Andric 5090b57cec5SDimitry Andric // If we have a modifier wrap the inner expression 5100b57cec5SDimitry Andric assert(Parser.getTok().getKind() == AsmToken::RParen); 5110b57cec5SDimitry Andric Parser.Lex(); // Eat closing parenthesis 5120b57cec5SDimitry Andric 513349cc55cSDimitry Andric MCExpr const *Expression = 514349cc55cSDimitry Andric AVRMCExpr::create(ModifierKind, InnerExpression, isNegated, getContext()); 5150b57cec5SDimitry Andric 5160b57cec5SDimitry Andric SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 5170b57cec5SDimitry Andric Operands.push_back(AVROperand::CreateImm(Expression, S, E)); 5180b57cec5SDimitry Andric 5190b57cec5SDimitry Andric return false; 5200b57cec5SDimitry Andric } 5210b57cec5SDimitry Andric 522bdd1243dSDimitry Andric bool AVRAsmParser::parseOperand(OperandVector &Operands, bool maybeReg) { 5230b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "parseOperand\n"); 5240b57cec5SDimitry Andric 5250b57cec5SDimitry Andric switch (getLexer().getKind()) { 5260b57cec5SDimitry Andric default: 5270b57cec5SDimitry Andric return Error(Parser.getTok().getLoc(), "unexpected token in operand"); 5280b57cec5SDimitry Andric 5290b57cec5SDimitry Andric case AsmToken::Identifier: 530bdd1243dSDimitry Andric // Try to parse a register, fall through to the next case if it fails. 531bdd1243dSDimitry Andric if (maybeReg && !tryParseRegisterOperand(Operands)) { 5320b57cec5SDimitry Andric return false; 5330b57cec5SDimitry Andric } 534bdd1243dSDimitry Andric [[fallthrough]]; 5350b57cec5SDimitry Andric case AsmToken::LParen: 5360b57cec5SDimitry Andric case AsmToken::Integer: 537*6c4b055cSDimitry Andric return tryParseExpression(Operands, 0); 5380b57cec5SDimitry Andric case AsmToken::Dot: 539*6c4b055cSDimitry Andric return tryParseExpression(Operands, 2); 5400b57cec5SDimitry Andric case AsmToken::Plus: 5410b57cec5SDimitry Andric case AsmToken::Minus: { 5420b57cec5SDimitry Andric // If the sign preceeds a number, parse the number, 5430b57cec5SDimitry Andric // otherwise treat the sign a an independent token. 5440b57cec5SDimitry Andric switch (getLexer().peekTok().getKind()) { 5450b57cec5SDimitry Andric case AsmToken::Integer: 5460b57cec5SDimitry Andric case AsmToken::BigNum: 5470b57cec5SDimitry Andric case AsmToken::Identifier: 5480b57cec5SDimitry Andric case AsmToken::Real: 549*6c4b055cSDimitry Andric if (!tryParseExpression(Operands, 0)) 5500b57cec5SDimitry Andric return false; 5510b57cec5SDimitry Andric break; 5520b57cec5SDimitry Andric default: 5530b57cec5SDimitry Andric break; 5540b57cec5SDimitry Andric } 5550b57cec5SDimitry Andric // Treat the token as an independent token. 5560b57cec5SDimitry Andric Operands.push_back(AVROperand::CreateToken(Parser.getTok().getString(), 5570b57cec5SDimitry Andric Parser.getTok().getLoc())); 5580b57cec5SDimitry Andric Parser.Lex(); // Eat the token. 5590b57cec5SDimitry Andric return false; 5600b57cec5SDimitry Andric } 5610b57cec5SDimitry Andric } 5620b57cec5SDimitry Andric 5630b57cec5SDimitry Andric // Could not parse operand 5640b57cec5SDimitry Andric return true; 5650b57cec5SDimitry Andric } 5660b57cec5SDimitry Andric 5675f757f3fSDimitry Andric ParseStatus AVRAsmParser::parseMemriOperand(OperandVector &Operands) { 5680b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "parseMemriOperand()\n"); 5690b57cec5SDimitry Andric 5700b57cec5SDimitry Andric SMLoc E, S; 5710b57cec5SDimitry Andric MCExpr const *Expression; 5720b57cec5SDimitry Andric int RegNo; 5730b57cec5SDimitry Andric 5740b57cec5SDimitry Andric // Parse register. 5750b57cec5SDimitry Andric { 5760b57cec5SDimitry Andric RegNo = parseRegister(); 5770b57cec5SDimitry Andric 5780b57cec5SDimitry Andric if (RegNo == AVR::NoRegister) 5795f757f3fSDimitry Andric return ParseStatus::Failure; 5800b57cec5SDimitry Andric 5810b57cec5SDimitry Andric S = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 5820b57cec5SDimitry Andric Parser.Lex(); // Eat register token. 5830b57cec5SDimitry Andric } 5840b57cec5SDimitry Andric 5850b57cec5SDimitry Andric // Parse immediate; 5860b57cec5SDimitry Andric { 5870b57cec5SDimitry Andric if (getParser().parseExpression(Expression)) 5885f757f3fSDimitry Andric return ParseStatus::Failure; 5890b57cec5SDimitry Andric 5900b57cec5SDimitry Andric E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 5910b57cec5SDimitry Andric } 5920b57cec5SDimitry Andric 5930b57cec5SDimitry Andric Operands.push_back(AVROperand::CreateMemri(RegNo, Expression, S, E)); 5940b57cec5SDimitry Andric 5955f757f3fSDimitry Andric return ParseStatus::Success; 5960b57cec5SDimitry Andric } 5970b57cec5SDimitry Andric 5985f757f3fSDimitry Andric bool AVRAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc, 5990b57cec5SDimitry Andric SMLoc &EndLoc) { 6000b57cec5SDimitry Andric StartLoc = Parser.getTok().getLoc(); 6015f757f3fSDimitry Andric Reg = parseRegister(/*RestoreOnFailure=*/false); 6020b57cec5SDimitry Andric EndLoc = Parser.getTok().getLoc(); 6030b57cec5SDimitry Andric 6045f757f3fSDimitry Andric return Reg == AVR::NoRegister; 6050b57cec5SDimitry Andric } 6060b57cec5SDimitry Andric 6075f757f3fSDimitry Andric ParseStatus AVRAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, 6085ffd83dbSDimitry Andric SMLoc &EndLoc) { 6095ffd83dbSDimitry Andric StartLoc = Parser.getTok().getLoc(); 6105f757f3fSDimitry Andric Reg = parseRegister(/*RestoreOnFailure=*/true); 6115ffd83dbSDimitry Andric EndLoc = Parser.getTok().getLoc(); 6125ffd83dbSDimitry Andric 6135f757f3fSDimitry Andric if (Reg == AVR::NoRegister) 6145f757f3fSDimitry Andric return ParseStatus::NoMatch; 6155f757f3fSDimitry Andric return ParseStatus::Success; 6165ffd83dbSDimitry Andric } 6175ffd83dbSDimitry Andric 6180b57cec5SDimitry Andric void AVRAsmParser::eatComma() { 6190b57cec5SDimitry Andric if (getLexer().is(AsmToken::Comma)) { 6200b57cec5SDimitry Andric Parser.Lex(); 6210b57cec5SDimitry Andric } else { 6220b57cec5SDimitry Andric // GCC allows commas to be omitted. 6230b57cec5SDimitry Andric } 6240b57cec5SDimitry Andric } 6250b57cec5SDimitry Andric 6260b57cec5SDimitry Andric bool AVRAsmParser::ParseInstruction(ParseInstructionInfo &Info, 6270b57cec5SDimitry Andric StringRef Mnemonic, SMLoc NameLoc, 6280b57cec5SDimitry Andric OperandVector &Operands) { 6290b57cec5SDimitry Andric Operands.push_back(AVROperand::CreateToken(Mnemonic, NameLoc)); 6300b57cec5SDimitry Andric 631bdd1243dSDimitry Andric int OperandNum = -1; 6320b57cec5SDimitry Andric while (getLexer().isNot(AsmToken::EndOfStatement)) { 633bdd1243dSDimitry Andric OperandNum++; 634bdd1243dSDimitry Andric if (OperandNum > 0) 635349cc55cSDimitry Andric eatComma(); 6360b57cec5SDimitry Andric 6375f757f3fSDimitry Andric ParseStatus ParseRes = MatchOperandParserImpl(Operands, Mnemonic); 6380b57cec5SDimitry Andric 6395f757f3fSDimitry Andric if (ParseRes.isSuccess()) 6400b57cec5SDimitry Andric continue; 6410b57cec5SDimitry Andric 6425f757f3fSDimitry Andric if (ParseRes.isFailure()) { 6430b57cec5SDimitry Andric SMLoc Loc = getLexer().getLoc(); 6440b57cec5SDimitry Andric Parser.eatToEndOfStatement(); 6450b57cec5SDimitry Andric 6460b57cec5SDimitry Andric return Error(Loc, "failed to parse register and immediate pair"); 6470b57cec5SDimitry Andric } 6480b57cec5SDimitry Andric 649bdd1243dSDimitry Andric // These specific operands should be treated as addresses/symbols/labels, 650bdd1243dSDimitry Andric // other than registers. 651bdd1243dSDimitry Andric bool maybeReg = true; 652*6c4b055cSDimitry Andric 653bdd1243dSDimitry Andric if (OperandNum == 1) { 654bdd1243dSDimitry Andric std::array<StringRef, 8> Insts = {"lds", "adiw", "sbiw", "ldi"}; 655bdd1243dSDimitry Andric for (auto Inst : Insts) { 656bdd1243dSDimitry Andric if (Inst == Mnemonic) { 657bdd1243dSDimitry Andric maybeReg = false; 658bdd1243dSDimitry Andric break; 659bdd1243dSDimitry Andric } 660bdd1243dSDimitry Andric } 661bdd1243dSDimitry Andric } else if (OperandNum == 0) { 662bdd1243dSDimitry Andric std::array<StringRef, 8> Insts = {"sts", "call", "rcall", "rjmp", "jmp"}; 663bdd1243dSDimitry Andric for (auto Inst : Insts) { 664bdd1243dSDimitry Andric if (Inst == Mnemonic) { 665bdd1243dSDimitry Andric maybeReg = false; 666bdd1243dSDimitry Andric break; 667bdd1243dSDimitry Andric } 668bdd1243dSDimitry Andric } 669bdd1243dSDimitry Andric } 670bdd1243dSDimitry Andric 671bdd1243dSDimitry Andric if (parseOperand(Operands, maybeReg)) { 6720b57cec5SDimitry Andric SMLoc Loc = getLexer().getLoc(); 6730b57cec5SDimitry Andric Parser.eatToEndOfStatement(); 6740b57cec5SDimitry Andric return Error(Loc, "unexpected token in argument list"); 6750b57cec5SDimitry Andric } 6760b57cec5SDimitry Andric } 6770b57cec5SDimitry Andric Parser.Lex(); // Consume the EndOfStatement 6780b57cec5SDimitry Andric return false; 6790b57cec5SDimitry Andric } 6800b57cec5SDimitry Andric 68106c3fb27SDimitry Andric ParseStatus AVRAsmParser::parseDirective(llvm::AsmToken DirectiveID) { 6820b57cec5SDimitry Andric StringRef IDVal = DirectiveID.getIdentifier(); 68306c3fb27SDimitry Andric if (IDVal.lower() == ".long") 68406c3fb27SDimitry Andric return parseLiteralValues(SIZE_LONG, DirectiveID.getLoc()); 68506c3fb27SDimitry Andric if (IDVal.lower() == ".word" || IDVal.lower() == ".short") 68606c3fb27SDimitry Andric return parseLiteralValues(SIZE_WORD, DirectiveID.getLoc()); 68706c3fb27SDimitry Andric if (IDVal.lower() == ".byte") 68806c3fb27SDimitry Andric return parseLiteralValues(1, DirectiveID.getLoc()); 68906c3fb27SDimitry Andric return ParseStatus::NoMatch; 6900b57cec5SDimitry Andric } 6910b57cec5SDimitry Andric 69206c3fb27SDimitry Andric ParseStatus AVRAsmParser::parseLiteralValues(unsigned SizeInBytes, SMLoc L) { 6930b57cec5SDimitry Andric MCAsmParser &Parser = getParser(); 6940b57cec5SDimitry Andric AVRMCELFStreamer &AVRStreamer = 6950b57cec5SDimitry Andric static_cast<AVRMCELFStreamer &>(Parser.getStreamer()); 6960b57cec5SDimitry Andric AsmToken Tokens[2]; 6970b57cec5SDimitry Andric size_t ReadCount = Parser.getLexer().peekTokens(Tokens); 6980b57cec5SDimitry Andric if (ReadCount == 2 && Parser.getTok().getKind() == AsmToken::Identifier && 6990b57cec5SDimitry Andric Tokens[0].getKind() == AsmToken::Minus && 7000b57cec5SDimitry Andric Tokens[1].getKind() == AsmToken::Identifier) { 7010b57cec5SDimitry Andric MCSymbol *Symbol = getContext().getOrCreateSymbol(".text"); 7025ffd83dbSDimitry Andric AVRStreamer.emitValueForModiferKind(Symbol, SizeInBytes, L, 7030b57cec5SDimitry Andric AVRMCExpr::VK_AVR_None); 70406c3fb27SDimitry Andric return ParseStatus::NoMatch; 7050b57cec5SDimitry Andric } 7060b57cec5SDimitry Andric 7070b57cec5SDimitry Andric if (Parser.getTok().getKind() == AsmToken::Identifier && 7080b57cec5SDimitry Andric Parser.getLexer().peekTok().getKind() == AsmToken::LParen) { 7090b57cec5SDimitry Andric StringRef ModifierName = Parser.getTok().getString(); 7100b57cec5SDimitry Andric AVRMCExpr::VariantKind ModifierKind = 711349cc55cSDimitry Andric AVRMCExpr::getKindByName(ModifierName); 7120b57cec5SDimitry Andric if (ModifierKind != AVRMCExpr::VK_AVR_None) { 7130b57cec5SDimitry Andric Parser.Lex(); 7140b57cec5SDimitry Andric Parser.Lex(); // Eat the modifier and parenthesis 7150b57cec5SDimitry Andric } else { 7160b57cec5SDimitry Andric return Error(Parser.getTok().getLoc(), "unknown modifier"); 7170b57cec5SDimitry Andric } 7180b57cec5SDimitry Andric MCSymbol *Symbol = 7190b57cec5SDimitry Andric getContext().getOrCreateSymbol(Parser.getTok().getString()); 7205ffd83dbSDimitry Andric AVRStreamer.emitValueForModiferKind(Symbol, SizeInBytes, L, ModifierKind); 72106c3fb27SDimitry Andric Lex(); // Eat the symbol name. 72206c3fb27SDimitry Andric if (parseToken(AsmToken::RParen)) 72306c3fb27SDimitry Andric return ParseStatus::Failure; 72406c3fb27SDimitry Andric return parseEOL(); 7250b57cec5SDimitry Andric } 7260b57cec5SDimitry Andric 7270b57cec5SDimitry Andric auto parseOne = [&]() -> bool { 7280b57cec5SDimitry Andric const MCExpr *Value; 7290b57cec5SDimitry Andric if (Parser.parseExpression(Value)) 7300b57cec5SDimitry Andric return true; 7315ffd83dbSDimitry Andric Parser.getStreamer().emitValue(Value, SizeInBytes, L); 7320b57cec5SDimitry Andric return false; 7330b57cec5SDimitry Andric }; 7340b57cec5SDimitry Andric return (parseMany(parseOne)); 7350b57cec5SDimitry Andric } 7360b57cec5SDimitry Andric 737480093f4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAVRAsmParser() { 7380b57cec5SDimitry Andric RegisterMCAsmParser<AVRAsmParser> X(getTheAVRTarget()); 7390b57cec5SDimitry Andric } 7400b57cec5SDimitry Andric 7410b57cec5SDimitry Andric #define GET_REGISTER_MATCHER 7420b57cec5SDimitry Andric #define GET_MATCHER_IMPLEMENTATION 7430b57cec5SDimitry Andric #include "AVRGenAsmMatcher.inc" 7440b57cec5SDimitry Andric 7450b57cec5SDimitry Andric // Uses enums defined in AVRGenAsmMatcher.inc 7460b57cec5SDimitry Andric unsigned AVRAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, 7470b57cec5SDimitry Andric unsigned ExpectedKind) { 7480b57cec5SDimitry Andric AVROperand &Op = static_cast<AVROperand &>(AsmOp); 7490b57cec5SDimitry Andric MatchClassKind Expected = static_cast<MatchClassKind>(ExpectedKind); 7500b57cec5SDimitry Andric 7510b57cec5SDimitry Andric // If need be, GCC converts bare numbers to register names 7520b57cec5SDimitry Andric // It's ugly, but GCC supports it. 7530b57cec5SDimitry Andric if (Op.isImm()) { 7540b57cec5SDimitry Andric if (MCConstantExpr const *Const = dyn_cast<MCConstantExpr>(Op.getImm())) { 7550b57cec5SDimitry Andric int64_t RegNum = Const->getValue(); 75681ad6265SDimitry Andric 75781ad6265SDimitry Andric // Reject R0~R15 on avrtiny. 75881ad6265SDimitry Andric if (0 <= RegNum && RegNum <= 15 && 75981ad6265SDimitry Andric STI.hasFeature(AVR::FeatureTinyEncoding)) 76081ad6265SDimitry Andric return Match_InvalidRegisterOnTiny; 76181ad6265SDimitry Andric 7620b57cec5SDimitry Andric std::ostringstream RegName; 7630b57cec5SDimitry Andric RegName << "r" << RegNum; 764349cc55cSDimitry Andric RegNum = MatchRegisterName(RegName.str()); 7650b57cec5SDimitry Andric if (RegNum != AVR::NoRegister) { 7660b57cec5SDimitry Andric Op.makeReg(RegNum); 7670b57cec5SDimitry Andric if (validateOperandClass(Op, Expected) == Match_Success) { 7680b57cec5SDimitry Andric return Match_Success; 7690b57cec5SDimitry Andric } 7700b57cec5SDimitry Andric } 7710b57cec5SDimitry Andric // Let the other quirks try their magic. 7720b57cec5SDimitry Andric } 7730b57cec5SDimitry Andric } 7740b57cec5SDimitry Andric 7750b57cec5SDimitry Andric if (Op.isReg()) { 7760b57cec5SDimitry Andric // If the instruction uses a register pair but we got a single, lower 7770b57cec5SDimitry Andric // register we perform a "class cast". 7780b57cec5SDimitry Andric if (isSubclass(Expected, MCK_DREGS)) { 7790b57cec5SDimitry Andric unsigned correspondingDREG = toDREG(Op.getReg()); 7800b57cec5SDimitry Andric 7810b57cec5SDimitry Andric if (correspondingDREG != AVR::NoRegister) { 7820b57cec5SDimitry Andric Op.makeReg(correspondingDREG); 7830b57cec5SDimitry Andric return validateOperandClass(Op, Expected); 7840b57cec5SDimitry Andric } 7850b57cec5SDimitry Andric } 7860b57cec5SDimitry Andric } 7870b57cec5SDimitry Andric return Match_InvalidOperand; 7880b57cec5SDimitry Andric } 789