diff options
Diffstat (limited to 'contrib/llvm/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp')
| -rw-r--r-- | contrib/llvm/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp | 580 |
1 files changed, 0 insertions, 580 deletions
diff --git a/contrib/llvm/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp b/contrib/llvm/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp deleted file mode 100644 index a0ec14ae2381..000000000000 --- a/contrib/llvm/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp +++ /dev/null @@ -1,580 +0,0 @@ -//===- MSP430AsmParser.cpp - Parse MSP430 assembly to MCInst instructions -===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "MSP430.h" -#include "MSP430RegisterInfo.h" -#include "MCTargetDesc/MSP430MCTargetDesc.h" -#include "TargetInfo/MSP430TargetInfo.h" - -#include "llvm/ADT/APInt.h" -#include "llvm/ADT/StringSwitch.h" -#include "llvm/MC/MCContext.h" -#include "llvm/MC/MCExpr.h" -#include "llvm/MC/MCInst.h" -#include "llvm/MC/MCInstBuilder.h" -#include "llvm/MC/MCParser/MCAsmLexer.h" -#include "llvm/MC/MCParser/MCParsedAsmOperand.h" -#include "llvm/MC/MCParser/MCTargetAsmParser.h" -#include "llvm/MC/MCStreamer.h" -#include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/MC/MCSymbol.h" -#include "llvm/MC/MCValue.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/MathExtras.h" -#include "llvm/Support/TargetRegistry.h" - -#define DEBUG_TYPE "msp430-asm-parser" - -using namespace llvm; - -namespace { - -/// Parses MSP430 assembly from a stream. -class MSP430AsmParser : public MCTargetAsmParser { - const MCSubtargetInfo &STI; - MCAsmParser &Parser; - const MCRegisterInfo *MRI; - - bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, - OperandVector &Operands, MCStreamer &Out, - uint64_t &ErrorInfo, - bool MatchingInlineAsm) override; - - bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; - - bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, - SMLoc NameLoc, OperandVector &Operands) override; - - bool ParseDirective(AsmToken DirectiveID) override; - bool ParseDirectiveRefSym(AsmToken DirectiveID); - - unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, - unsigned Kind) override; - - bool parseJccInstruction(ParseInstructionInfo &Info, StringRef Name, - SMLoc NameLoc, OperandVector &Operands); - - bool ParseOperand(OperandVector &Operands); - - bool ParseLiteralValues(unsigned Size, SMLoc L); - - MCAsmParser &getParser() const { return Parser; } - MCAsmLexer &getLexer() const { return Parser.getLexer(); } - - /// @name Auto-generated Matcher Functions - /// { - -#define GET_ASSEMBLER_HEADER -#include "MSP430GenAsmMatcher.inc" - - /// } - -public: - MSP430AsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, - const MCInstrInfo &MII, const MCTargetOptions &Options) - : MCTargetAsmParser(Options, STI, MII), STI(STI), Parser(Parser) { - MCAsmParserExtension::Initialize(Parser); - MRI = getContext().getRegisterInfo(); - - setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); - } -}; - -/// A parsed MSP430 assembly operand. -class MSP430Operand : public MCParsedAsmOperand { - typedef MCParsedAsmOperand Base; - - enum KindTy { - k_Imm, - k_Reg, - k_Tok, - k_Mem, - k_IndReg, - k_PostIndReg - } Kind; - - struct Memory { - unsigned Reg; - const MCExpr *Offset; - }; - union { - const MCExpr *Imm; - unsigned Reg; - StringRef Tok; - Memory Mem; - }; - - SMLoc Start, End; - -public: - MSP430Operand(StringRef Tok, SMLoc const &S) - : Base(), Kind(k_Tok), Tok(Tok), Start(S), End(S) {} - MSP430Operand(KindTy Kind, unsigned Reg, SMLoc const &S, SMLoc const &E) - : Base(), Kind(Kind), Reg(Reg), Start(S), End(E) {} - MSP430Operand(MCExpr const *Imm, SMLoc const &S, SMLoc const &E) - : Base(), Kind(k_Imm), Imm(Imm), Start(S), End(E) {} - MSP430Operand(unsigned Reg, MCExpr const *Expr, SMLoc const &S, SMLoc const &E) - : Base(), Kind(k_Mem), Mem({Reg, Expr}), Start(S), End(E) {} - - void addRegOperands(MCInst &Inst, unsigned N) const { - assert((Kind == k_Reg || Kind == k_IndReg || Kind == k_PostIndReg) && - "Unexpected operand kind"); - assert(N == 1 && "Invalid number of operands!"); - - Inst.addOperand(MCOperand::createReg(Reg)); - } - - void addExprOperand(MCInst &Inst, const MCExpr *Expr) const { - // Add as immediate when possible - if (!Expr) - Inst.addOperand(MCOperand::createImm(0)); - else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) - Inst.addOperand(MCOperand::createImm(CE->getValue())); - else - Inst.addOperand(MCOperand::createExpr(Expr)); - } - - void addImmOperands(MCInst &Inst, unsigned N) const { - assert(Kind == k_Imm && "Unexpected operand kind"); - assert(N == 1 && "Invalid number of operands!"); - - addExprOperand(Inst, Imm); - } - - void addMemOperands(MCInst &Inst, unsigned N) const { - assert(Kind == k_Mem && "Unexpected operand kind"); - assert(N == 2 && "Invalid number of operands"); - - Inst.addOperand(MCOperand::createReg(Mem.Reg)); - addExprOperand(Inst, Mem.Offset); - } - - bool isReg() const { return Kind == k_Reg; } - bool isImm() const { return Kind == k_Imm; } - bool isToken() const { return Kind == k_Tok; } - bool isMem() const { return Kind == k_Mem; } - bool isIndReg() const { return Kind == k_IndReg; } - bool isPostIndReg() const { return Kind == k_PostIndReg; } - - bool isCGImm() const { - if (Kind != k_Imm) - return false; - - int64_t Val; - if (!Imm->evaluateAsAbsolute(Val)) - return false; - - if (Val == 0 || Val == 1 || Val == 2 || Val == 4 || Val == 8 || Val == -1) - return true; - - return false; - } - - StringRef getToken() const { - assert(Kind == k_Tok && "Invalid access!"); - return Tok; - } - - unsigned getReg() const { - assert(Kind == k_Reg && "Invalid access!"); - return Reg; - } - - void setReg(unsigned RegNo) { - assert(Kind == k_Reg && "Invalid access!"); - Reg = RegNo; - } - - static std::unique_ptr<MSP430Operand> CreateToken(StringRef Str, SMLoc S) { - return make_unique<MSP430Operand>(Str, S); - } - - static std::unique_ptr<MSP430Operand> CreateReg(unsigned RegNum, SMLoc S, - SMLoc E) { - return make_unique<MSP430Operand>(k_Reg, RegNum, S, E); - } - - static std::unique_ptr<MSP430Operand> CreateImm(const MCExpr *Val, SMLoc S, - SMLoc E) { - return make_unique<MSP430Operand>(Val, S, E); - } - - static std::unique_ptr<MSP430Operand> CreateMem(unsigned RegNum, - const MCExpr *Val, - SMLoc S, SMLoc E) { - return make_unique<MSP430Operand>(RegNum, Val, S, E); - } - - static std::unique_ptr<MSP430Operand> CreateIndReg(unsigned RegNum, SMLoc S, - SMLoc E) { - return make_unique<MSP430Operand>(k_IndReg, RegNum, S, E); - } - - static std::unique_ptr<MSP430Operand> CreatePostIndReg(unsigned RegNum, SMLoc S, - SMLoc E) { - return make_unique<MSP430Operand>(k_PostIndReg, RegNum, S, E); - } - - SMLoc getStartLoc() const { return Start; } - SMLoc getEndLoc() const { return End; } - - virtual void print(raw_ostream &O) const { - switch (Kind) { - case k_Tok: - O << "Token " << Tok; - break; - case k_Reg: - O << "Register " << Reg; - break; - case k_Imm: - O << "Immediate " << *Imm; - break; - case k_Mem: - O << "Memory "; - O << *Mem.Offset << "(" << Reg << ")"; - break; - case k_IndReg: - O << "RegInd " << Reg; - break; - case k_PostIndReg: - O << "PostInc " << Reg; - break; - } - } -}; -} // end anonymous namespace - -bool MSP430AsmParser::MatchAndEmitInstruction(SMLoc Loc, unsigned &Opcode, - OperandVector &Operands, - MCStreamer &Out, - uint64_t &ErrorInfo, - bool MatchingInlineAsm) { - MCInst Inst; - unsigned MatchResult = - MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); - - switch (MatchResult) { - case Match_Success: - Inst.setLoc(Loc); - Out.EmitInstruction(Inst, STI); - return false; - case Match_MnemonicFail: - return Error(Loc, "invalid instruction mnemonic"); - case Match_InvalidOperand: { - SMLoc ErrorLoc = Loc; - if (ErrorInfo != ~0U) { - if (ErrorInfo >= Operands.size()) - return Error(ErrorLoc, "too few operands for instruction"); - - ErrorLoc = ((MSP430Operand &)*Operands[ErrorInfo]).getStartLoc(); - if (ErrorLoc == SMLoc()) - ErrorLoc = Loc; - } - return Error(ErrorLoc, "invalid operand for instruction"); - } - default: - return true; - } -} - -// Auto-generated by TableGen -static unsigned MatchRegisterName(StringRef Name); -static unsigned MatchRegisterAltName(StringRef Name); - -bool MSP430AsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, - SMLoc &EndLoc) { - if (getLexer().getKind() == AsmToken::Identifier) { - auto Name = getLexer().getTok().getIdentifier().lower(); - RegNo = MatchRegisterName(Name); - if (RegNo == MSP430::NoRegister) { - RegNo = MatchRegisterAltName(Name); - if (RegNo == MSP430::NoRegister) - return true; - } - - AsmToken const &T = getParser().getTok(); - StartLoc = T.getLoc(); - EndLoc = T.getEndLoc(); - getLexer().Lex(); // eat register token - - return false; - } - - return Error(StartLoc, "invalid register name"); -} - -bool MSP430AsmParser::parseJccInstruction(ParseInstructionInfo &Info, - StringRef Name, SMLoc NameLoc, - OperandVector &Operands) { - if (!Name.startswith_lower("j")) - return true; - - auto CC = Name.drop_front().lower(); - unsigned CondCode; - if (CC == "ne" || CC == "nz") - CondCode = MSP430CC::COND_NE; - else if (CC == "eq" || CC == "z") - CondCode = MSP430CC::COND_E; - else if (CC == "lo" || CC == "nc") - CondCode = MSP430CC::COND_LO; - else if (CC == "hs" || CC == "c") - CondCode = MSP430CC::COND_HS; - else if (CC == "n") - CondCode = MSP430CC::COND_N; - else if (CC == "ge") - CondCode = MSP430CC::COND_GE; - else if (CC == "l") - CondCode = MSP430CC::COND_L; - else if (CC == "mp") - CondCode = MSP430CC::COND_NONE; - else - return Error(NameLoc, "unknown instruction"); - - if (CondCode == (unsigned)MSP430CC::COND_NONE) - Operands.push_back(MSP430Operand::CreateToken("jmp", NameLoc)); - else { - Operands.push_back(MSP430Operand::CreateToken("j", NameLoc)); - const MCExpr *CCode = MCConstantExpr::create(CondCode, getContext()); - Operands.push_back(MSP430Operand::CreateImm(CCode, SMLoc(), SMLoc())); - } - - // Skip optional '$' sign. - if (getLexer().getKind() == AsmToken::Dollar) - getLexer().Lex(); // Eat '$' - - const MCExpr *Val; - SMLoc ExprLoc = getLexer().getLoc(); - if (getParser().parseExpression(Val)) - return Error(ExprLoc, "expected expression operand"); - - int64_t Res; - if (Val->evaluateAsAbsolute(Res)) - if (Res < -512 || Res > 511) - return Error(ExprLoc, "invalid jump offset"); - - Operands.push_back(MSP430Operand::CreateImm(Val, ExprLoc, - getLexer().getLoc())); - - if (getLexer().isNot(AsmToken::EndOfStatement)) { - SMLoc Loc = getLexer().getLoc(); - getParser().eatToEndOfStatement(); - return Error(Loc, "unexpected token"); - } - - getParser().Lex(); // Consume the EndOfStatement. - return false; -} - -bool MSP430AsmParser::ParseInstruction(ParseInstructionInfo &Info, - StringRef Name, SMLoc NameLoc, - OperandVector &Operands) { - // Drop .w suffix - if (Name.endswith_lower(".w")) - Name = Name.drop_back(2); - - if (!parseJccInstruction(Info, Name, NameLoc, Operands)) - return false; - - // First operand is instruction mnemonic - Operands.push_back(MSP430Operand::CreateToken(Name, NameLoc)); - - // If there are no more operands, then finish - if (getLexer().is(AsmToken::EndOfStatement)) - return false; - - // Parse first operand - if (ParseOperand(Operands)) - return true; - - // Parse second operand if any - if (getLexer().is(AsmToken::Comma)) { - getLexer().Lex(); // Eat ',' - if (ParseOperand(Operands)) - return true; - } - - if (getLexer().isNot(AsmToken::EndOfStatement)) { - SMLoc Loc = getLexer().getLoc(); - getParser().eatToEndOfStatement(); - return Error(Loc, "unexpected token"); - } - - getParser().Lex(); // Consume the EndOfStatement. - return false; -} - -bool MSP430AsmParser::ParseDirectiveRefSym(AsmToken DirectiveID) { - StringRef Name; - if (getParser().parseIdentifier(Name)) - return TokError("expected identifier in directive"); - - MCSymbol *Sym = getContext().getOrCreateSymbol(Name); - getStreamer().EmitSymbolAttribute(Sym, MCSA_Global); - return false; -} - -bool MSP430AsmParser::ParseDirective(AsmToken DirectiveID) { - StringRef IDVal = DirectiveID.getIdentifier(); - if (IDVal.lower() == ".long") { - ParseLiteralValues(4, DirectiveID.getLoc()); - } else if (IDVal.lower() == ".word" || IDVal.lower() == ".short") { - ParseLiteralValues(2, DirectiveID.getLoc()); - } else if (IDVal.lower() == ".byte") { - ParseLiteralValues(1, DirectiveID.getLoc()); - } else if (IDVal.lower() == ".refsym") { - return ParseDirectiveRefSym(DirectiveID); - } - return true; -} - -bool MSP430AsmParser::ParseOperand(OperandVector &Operands) { - switch (getLexer().getKind()) { - default: return true; - case AsmToken::Identifier: { - // try rN - unsigned RegNo; - SMLoc StartLoc, EndLoc; - if (!ParseRegister(RegNo, StartLoc, EndLoc)) { - Operands.push_back(MSP430Operand::CreateReg(RegNo, StartLoc, EndLoc)); - return false; - } - LLVM_FALLTHROUGH; - } - case AsmToken::Integer: - case AsmToken::Plus: - case AsmToken::Minus: { - SMLoc StartLoc = getParser().getTok().getLoc(); - const MCExpr *Val; - // Try constexpr[(rN)] - if (!getParser().parseExpression(Val)) { - unsigned RegNo = MSP430::PC; - SMLoc EndLoc = getParser().getTok().getLoc(); - // Try (rN) - if (getLexer().getKind() == AsmToken::LParen) { - getLexer().Lex(); // Eat '(' - SMLoc RegStartLoc; - if (ParseRegister(RegNo, RegStartLoc, EndLoc)) - return true; - if (getLexer().getKind() != AsmToken::RParen) - return true; - EndLoc = getParser().getTok().getEndLoc(); - getLexer().Lex(); // Eat ')' - } - Operands.push_back(MSP430Operand::CreateMem(RegNo, Val, StartLoc, - EndLoc)); - return false; - } - return true; - } - case AsmToken::Amp: { - // Try &constexpr - SMLoc StartLoc = getParser().getTok().getLoc(); - getLexer().Lex(); // Eat '&' - const MCExpr *Val; - if (!getParser().parseExpression(Val)) { - SMLoc EndLoc = getParser().getTok().getLoc(); - Operands.push_back(MSP430Operand::CreateMem(MSP430::SR, Val, StartLoc, - EndLoc)); - return false; - } - return true; - } - case AsmToken::At: { - // Try @rN[+] - SMLoc StartLoc = getParser().getTok().getLoc(); - getLexer().Lex(); // Eat '@' - unsigned RegNo; - SMLoc RegStartLoc, EndLoc; - if (ParseRegister(RegNo, RegStartLoc, EndLoc)) - return true; - if (getLexer().getKind() == AsmToken::Plus) { - Operands.push_back(MSP430Operand::CreatePostIndReg(RegNo, StartLoc, EndLoc)); - getLexer().Lex(); // Eat '+' - return false; - } - if (Operands.size() > 1) // Emulate @rd in destination position as 0(rd) - Operands.push_back(MSP430Operand::CreateMem(RegNo, - MCConstantExpr::create(0, getContext()), StartLoc, EndLoc)); - else - Operands.push_back(MSP430Operand::CreateIndReg(RegNo, StartLoc, EndLoc)); - return false; - } - case AsmToken::Hash: - // Try #constexpr - SMLoc StartLoc = getParser().getTok().getLoc(); - getLexer().Lex(); // Eat '#' - const MCExpr *Val; - if (!getParser().parseExpression(Val)) { - SMLoc EndLoc = getParser().getTok().getLoc(); - Operands.push_back(MSP430Operand::CreateImm(Val, StartLoc, EndLoc)); - return false; - } - return true; - } -} - -bool MSP430AsmParser::ParseLiteralValues(unsigned Size, SMLoc L) { - auto parseOne = [&]() -> bool { - const MCExpr *Value; - if (getParser().parseExpression(Value)) - return true; - getParser().getStreamer().EmitValue(Value, Size, L); - return false; - }; - return (parseMany(parseOne)); -} - -extern "C" void LLVMInitializeMSP430AsmParser() { - RegisterMCAsmParser<MSP430AsmParser> X(getTheMSP430Target()); -} - -#define GET_REGISTER_MATCHER -#define GET_MATCHER_IMPLEMENTATION -#include "MSP430GenAsmMatcher.inc" - -static unsigned convertGR16ToGR8(unsigned Reg) { - switch (Reg) { - default: - llvm_unreachable("Unknown GR16 register"); - case MSP430::PC: return MSP430::PCB; - case MSP430::SP: return MSP430::SPB; - case MSP430::SR: return MSP430::SRB; - case MSP430::CG: return MSP430::CGB; - case MSP430::FP: return MSP430::FPB; - case MSP430::R5: return MSP430::R5B; - case MSP430::R6: return MSP430::R6B; - case MSP430::R7: return MSP430::R7B; - case MSP430::R8: return MSP430::R8B; - case MSP430::R9: return MSP430::R9B; - case MSP430::R10: return MSP430::R10B; - case MSP430::R11: return MSP430::R11B; - case MSP430::R12: return MSP430::R12B; - case MSP430::R13: return MSP430::R13B; - case MSP430::R14: return MSP430::R14B; - case MSP430::R15: return MSP430::R15B; - } -} - -unsigned MSP430AsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, - unsigned Kind) { - MSP430Operand &Op = static_cast<MSP430Operand &>(AsmOp); - - if (!Op.isReg()) - return Match_InvalidOperand; - - unsigned Reg = Op.getReg(); - bool isGR16 = - MSP430MCRegisterClasses[MSP430::GR16RegClassID].contains(Reg); - - if (isGR16 && (Kind == MCK_GR8)) { - Op.setReg(convertGR16ToGR8(Reg)); - return Match_Success; - } - - return Match_InvalidOperand; -} |
