diff options
author | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2011-01-20 18:06:58 +0000 |
---|---|---|
committer | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2011-01-20 18:06:58 +0000 |
commit | b32f7a5f4bc678c052db40cbb4ac8617c134aa24 (patch) | |
tree | e0ba26360c94d2f633a4902158a22a06acb244a8 /lib/Target/ARM | |
parent | c0de99571297720a37ae405c77fb2ef4aaf00ccd (diff) | |
download | external_llvm-b32f7a5f4bc678c052db40cbb4ac8617c134aa24.zip external_llvm-b32f7a5f4bc678c052db40cbb4ac8617c134aa24.tar.gz external_llvm-b32f7a5f4bc678c052db40cbb4ac8617c134aa24.tar.bz2 |
- Use a more appropriate name for Owen's ARM Parser isMCR hack since the same operands can be present
in cdp/cdp2 instructions. Also increase the hack with cdp/cdp2 instructions.
- Fix the encoding of cdp/cdp2 instructions for ARM (no thumb and thumb2 yet) and add testcases for t
hem.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123927 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM')
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 44 | ||||
-rw-r--r-- | lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 42 |
2 files changed, 60 insertions, 26 deletions
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 8e07f8f..05b180e 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -3555,19 +3555,45 @@ include "ARMInstrNEON.td" // Coprocessor Instructions. For disassembly only. // -def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1, - nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2), - NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2", - [/* For disassembly only; pattern left blank */]> { - let Inst{4} = 0; +def CDP : ABI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1, + c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2), + NoItinerary, "cdp", "\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2", + [/* For disassembly only; pattern left blank */]> { + bits<4> opc1; + bits<4> CRn; + bits<4> CRd; + bits<4> cop; + bits<3> opc2; + bits<4> CRm; + + let Inst{3-0} = CRm; + let Inst{4} = 0; + let Inst{7-5} = opc2; + let Inst{11-8} = cop; + let Inst{15-12} = CRd; + let Inst{19-16} = CRn; + let Inst{23-20} = opc1; } -def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1, - nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2), - NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2", +def CDP2 : ABXI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1, + c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2), + NoItinerary, "cdp2\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2", [/* For disassembly only; pattern left blank */]> { let Inst{31-28} = 0b1111; - let Inst{4} = 0; + bits<4> opc1; + bits<4> CRn; + bits<4> CRd; + bits<4> cop; + bits<3> opc2; + bits<4> CRm; + + let Inst{3-0} = CRm; + let Inst{4} = 0; + let Inst{7-5} = opc2; + let Inst{11-8} = cop; + let Inst{15-12} = CRd; + let Inst{19-16} = CRn; + let Inst{23-20} = opc1; } class ACI<dag oops, dag iops, string opc, string asm> diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index ba42b1e..a10e158 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -53,11 +53,11 @@ class ARMAsmParser : public TargetAsmParser { bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } int TryParseRegister(); - bool TryParseMCRName(SmallVectorImpl<MCParsedAsmOperand*>&); + bool TryParseCoprocessorOperandName(SmallVectorImpl<MCParsedAsmOperand*>&); bool TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &); bool ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &); bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &); - bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, bool isMCR); + bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, bool hasCoprocOp); bool ParsePrefix(ARMMCExpr::VariantKind &RefKind); const MCExpr *ApplyPrefixToExpr(const MCExpr *E, MCSymbolRefExpr::VariantKind Variant); @@ -602,7 +602,7 @@ TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { return false; } -static int MatchMCRName(StringRef Name) { +static int MatchCoprocessorOperandName(StringRef Name) { // Use the same layout as the tablegen'erated register name matcher. Ugly, // but efficient. switch (Name.size()) { @@ -643,17 +643,18 @@ static int MatchMCRName(StringRef Name) { return -1; } -/// TryParseMCRName - Try to parse an MCR/MRC symbolic operand -/// name. The token must be an Identifier when called, and if it is a MCR -/// operand name, the token is eaten and the operand is added to the -/// operand list. +/// TryParseCoprocessorOperandName - Try to parse an coprocessor related +/// instruction with a symbolic operand name. The token must be an Identifier +/// when called, and if it is a coprocessor related operand name, the token is +/// eaten and the operand is added to the operand list. Example: operands like +/// "p1", "p7", "c3", "c5", ... bool ARMAsmParser:: -TryParseMCRName(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { +TryParseCoprocessorOperandName(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { SMLoc S = Parser.getTok().getLoc(); const AsmToken &Tok = Parser.getTok(); assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); - int Num = MatchMCRName(Tok.getString()); + int Num = MatchCoprocessorOperandName(Tok.getString()); if (Num == -1) return true; @@ -966,7 +967,7 @@ bool ARMAsmParser::ParseShift(ShiftType &St, const MCExpr *&ShiftAmount, /// Parse a arm instruction operand. For now this parses the operand regardless /// of the mnemonic. bool ARMAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, - bool isMCR){ + bool hasCoprocOp){ SMLoc S, E; switch (getLexer().getKind()) { default: @@ -975,7 +976,7 @@ bool ARMAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, case AsmToken::Identifier: if (!TryParseRegisterWithWriteBack(Operands)) return false; - if (isMCR && !TryParseMCRName(Operands)) + if (hasCoprocOp && !TryParseCoprocessorOperandName(Operands)) return false; // Fall though for the Identifier case that is not a register or a @@ -1264,15 +1265,22 @@ bool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, Operands.push_back(ARMOperand::CreateToken(Head, NameLoc)); } - bool isMCR = (Head == "mcr" || Head == "mcr2" || - Head == "mcrr" || Head == "mcrr2" || - Head == "mrc" || Head == "mrc2" || - Head == "mrrc" || Head == "mrrc2"); + // Enable the parsing of instructions containing coprocessor related + // asm syntax, such as coprocessor names "p7, p15, ..." and coprocessor + // registers "c1, c3, ..." + // FIXME: we probably want AsmOperandClass and ParserMatchClass declarations + // in the .td file rather than hacking the ASMParser for every symbolic + // operand type. + bool hasCoprocOp = (Head == "mcr" || Head == "mcr2" || + Head == "mcrr" || Head == "mcrr2" || + Head == "mrc" || Head == "mrc2" || + Head == "mrrc" || Head == "mrrc2" || + Head == "cdp" || Head == "cdp2"); // Read the remaining operands. if (getLexer().isNot(AsmToken::EndOfStatement)) { // Read the first operand. - if (ParseOperand(Operands, isMCR)) { + if (ParseOperand(Operands, hasCoprocOp)) { Parser.EatToEndOfStatement(); return true; } @@ -1281,7 +1289,7 @@ bool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, Parser.Lex(); // Eat the comma. // Parse and remember the operand. - if (ParseOperand(Operands, isMCR)) { + if (ParseOperand(Operands, hasCoprocOp)) { Parser.EatToEndOfStatement(); return true; } |