From: Kevin Enderby Date: Fri, 9 Oct 2009 21:12:28 +0000 (+0000) Subject: Added another bit of the ARM target assembler to llvm-mc to parse register X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=d7894f105a3c397a3d7f5c5136eee39f5865e64b;p=oota-llvm.git Added another bit of the ARM target assembler to llvm-mc to parse register lists. Changed ARMAsmParser::MatchRegisterName to return -1 instead of 0 on errors so 0-15 values could be returned as register numbers. Also added the rest of the arm register names to the currently hacked up version to allow more testing. Some changes to ARMAsmParser::ParseOperand to give different errors for things not yet supported and some additions to the hacked ARMAsmParser::MatchInstruction to allow more testing for now. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83673 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index c4244c72019..f64b62b2792 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -46,6 +46,8 @@ private: bool ParseRegister(ARMOperand &Op); + bool ParseRegisterList(ARMOperand &Op); + bool ParseMemory(ARMOperand &Op); bool ParseShift(enum ShiftType *St, const MCExpr *ShiftAmount); @@ -62,9 +64,11 @@ private: bool MatchInstruction(SmallVectorImpl &Operands, MCInst &Inst); - /// MatchRegisterName - Match the given string to a register name, or 0 if - /// there is no match. - unsigned MatchRegisterName(const StringRef &Name); + /// MatchRegisterName - Match the given string to a register name and return + /// its register number, or -1 if there is no match. To allow return values + /// to be used directly in register lists, arm registers have values between + /// 0 and 15. + int MatchRegisterName(const StringRef &Name); /// } @@ -190,10 +194,10 @@ bool ARMAsmParser::ParseRegister(ARMOperand &Op) { // FIXME: Validate register for the current architecture; we have to do // validation later, so maybe there is no need for this here. - unsigned RegNum; + int RegNum; RegNum = MatchRegisterName(Tok.getString()); - if (RegNum == 0) + if (RegNum == -1) return true; getLexer().Lex(); // Eat identifier token. @@ -209,6 +213,53 @@ bool ARMAsmParser::ParseRegister(ARMOperand &Op) { return false; } +// Try to parse a register list. The first token must be a '{' when called +// for now. +bool ARMAsmParser::ParseRegisterList(ARMOperand &Op) { + const AsmToken &LCurlyTok = getLexer().getTok(); + assert(LCurlyTok.is(AsmToken::LCurly) && "Token is not an Left Curly Brace"); + getLexer().Lex(); // Eat left curly brace token. + + const AsmToken &RegTok = getLexer().getTok(); + SMLoc RegLoc = RegTok.getLoc(); + if (RegTok.isNot(AsmToken::Identifier)) + return Error(RegLoc, "register expected"); + int RegNum = MatchRegisterName(RegTok.getString()); + if (RegNum == -1) + return Error(RegLoc, "register expected"); + getLexer().Lex(); // Eat identifier token. + unsigned RegList = 1 << RegNum; + + int HighRegNum = RegNum; + // TODO ranges like "{Rn-Rm}" + while (getLexer().getTok().is(AsmToken::Comma)) { + getLexer().Lex(); // Eat comma token. + + const AsmToken &RegTok = getLexer().getTok(); + SMLoc RegLoc = RegTok.getLoc(); + if (RegTok.isNot(AsmToken::Identifier)) + return Error(RegLoc, "register expected"); + int RegNum = MatchRegisterName(RegTok.getString()); + if (RegNum == -1) + return Error(RegLoc, "register expected"); + + if (RegList & (1 << RegNum)) + Warning(RegLoc, "register duplicated in register list"); + else if (RegNum <= HighRegNum) + Warning(RegLoc, "register not in ascending order in register list"); + RegList |= 1 << RegNum; + HighRegNum = RegNum; + + getLexer().Lex(); // Eat identifier token. + } + const AsmToken &RCurlyTok = getLexer().getTok(); + if (RCurlyTok.isNot(AsmToken::RCurly)) + return Error(RCurlyTok.getLoc(), "'}' expected"); + getLexer().Lex(); // Eat left curly brace token. + + return false; +} + // Try to parse an arm memory expression. It must start with a '[' token. // TODO Only preindexing and postindexing addressing are started, unindexed // with option, etc are still to do. @@ -220,8 +271,8 @@ bool ARMAsmParser::ParseMemory(ARMOperand &Op) { const AsmToken &BaseRegTok = getLexer().getTok(); if (BaseRegTok.isNot(AsmToken::Identifier)) return Error(BaseRegTok.getLoc(), "register expected"); - unsigned BaseRegNum = MatchRegisterName(BaseRegTok.getString()); - if (BaseRegNum == 0) + int BaseRegNum = MatchRegisterName(BaseRegTok.getString()); + if (BaseRegNum == -1) return Error(BaseRegTok.getLoc(), "register expected"); getLexer().Lex(); // Eat identifier token. @@ -251,12 +302,12 @@ bool ARMAsmParser::ParseMemory(ARMOperand &Op) { // See if there is a register following the "[Rn," we have so far. const AsmToken &OffsetRegTok = getLexer().getTok(); - unsigned OffsetRegNum = MatchRegisterName(OffsetRegTok.getString()); + int OffsetRegNum = MatchRegisterName(OffsetRegTok.getString()); bool OffsetRegShifted = false; enum ShiftType ShiftType; const MCExpr *ShiftAmount; const MCExpr *Offset; - if (OffsetRegNum != 0) { + if (OffsetRegNum != -1) { OffsetIsReg = true; getLexer().Lex(); // Eat identifier token for the offset register. // Look for a comma then a shift @@ -321,12 +372,12 @@ bool ARMAsmParser::ParseMemory(ARMOperand &Op) { // See if there is a register following the "[Rn]," we have so far. const AsmToken &OffsetRegTok = getLexer().getTok(); - unsigned OffsetRegNum = MatchRegisterName(OffsetRegTok.getString()); + int OffsetRegNum = MatchRegisterName(OffsetRegTok.getString()); bool OffsetRegShifted = false; enum ShiftType ShiftType; const MCExpr *ShiftAmount; const MCExpr *Offset; - if (OffsetRegNum != 0) { + if (OffsetRegNum != -1) { OffsetIsReg = true; getLexer().Lex(); // Eat identifier token for the offset register. // Look for a comma then a shift @@ -398,16 +449,42 @@ bool ARMAsmParser::ParseShift(ShiftType *St, const MCExpr *ShiftAmount) { } // A hack to allow some testing -unsigned ARMAsmParser::MatchRegisterName(const StringRef &Name) { - if (Name == "r1") +int ARMAsmParser::MatchRegisterName(const StringRef &Name) { + if (Name == "r0" || Name == "R0") + return 0; + else if (Name == "r1" || Name == "R1") return 1; - else if (Name == "r2") + else if (Name == "r2" || Name == "R2") return 2; - else if (Name == "r3") + else if (Name == "r3" || Name == "R3") return 3; - else if (Name == "sp") + else if (Name == "r3" || Name == "R3") + return 3; + else if (Name == "r4" || Name == "R4") + return 4; + else if (Name == "r5" || Name == "R5") + return 5; + else if (Name == "r6" || Name == "R6") + return 6; + else if (Name == "r7" || Name == "R7") + return 7; + else if (Name == "r8" || Name == "R8") + return 8; + else if (Name == "r9" || Name == "R9") + return 9; + else if (Name == "r10" || Name == "R10") + return 10; + else if (Name == "r11" || Name == "R11" || Name == "fp") + return 11; + else if (Name == "r12" || Name == "R12" || Name == "ip") + return 12; + else if (Name == "r13" || Name == "R13" || Name == "sp") return 13; - return 0; + else if (Name == "r14" || Name == "R14" || Name == "lr") + return 14; + else if (Name == "r15" || Name == "R15" || Name == "pc") + return 15; + return -1; } // A hack to allow some testing @@ -420,7 +497,8 @@ bool ARMAsmParser::MatchInstruction(SmallVectorImpl &Operands, Mnemonic == "stmfd" || Mnemonic == "str" || Mnemonic == "ldmfd" || - Mnemonic == "ldr") + Mnemonic == "ldr" || + Mnemonic == "mov") return false; return true; @@ -432,13 +510,18 @@ bool ARMAsmParser::ParseOperand(ARMOperand &Op) { case AsmToken::Identifier: if (!ParseRegister(Op)) return false; - // TODO parse other operands that start with an identifier - return true; + // TODO parse other operands that start with an identifier like labels + return Error(getLexer().getTok().getLoc(), "labels not yet supported"); case AsmToken::LBrac: if (!ParseMemory(Op)) return false; + case AsmToken::LCurly: + if (!ParseRegisterList(Op)) + return(false); + case AsmToken::Hash: + return Error(getLexer().getTok().getLoc(), "immediates not yet supported"); default: - return true; + return Error(getLexer().getTok().getLoc(), "unexpected token in operand"); } }