From: Jim Grosbach Date: Fri, 22 Jul 2011 17:44:50 +0000 (+0000) Subject: ARM assembly parsing and encoding for SETEND instruction. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=c27d4f9ea0cb9064d3e2cadb384d73e95e9de449;p=oota-llvm.git ARM assembly parsing and encoding for SETEND instruction. Add parsing and diagnostics for malformed inputs. Tests for diagnostics and for correct encodings. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135776 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index e673fe71e84..278bd5bda79 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -193,8 +193,13 @@ def s_cc_out : OptionalDefOperand { // ARM special operands for disassembly only. // +def SetEndAsmOperand : AsmOperandClass { + let Name = "SetEndImm"; + let ParserMethod = "parseSetEndImm"; +} def setend_op : Operand { let PrintMethod = "printSetendOperand"; + let ParserMatchClass = SetEndAsmOperand; } def msr_mask : Operand { diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index fd8f815207d..ef611b21e72 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -126,6 +126,7 @@ class ARMAsmParser : public TargetAsmParser { OperandMatchResultTy parsePKHASRImm(SmallVectorImpl &O) { return parsePKHImm(O, "asr", 1, 32); } + OperandMatchResultTy parseSetEndImm(SmallVectorImpl&); // Asm Match Converter Methods bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, @@ -476,6 +477,14 @@ public: int64_t Value = CE->getValue(); return ARM_AM::getT2SOImmVal(Value) != -1; } + bool isSetEndImm() const { + if (Kind != Immediate) + return false; + const MCConstantExpr *CE = dyn_cast(getImm()); + if (!CE) return false; + int64_t Value = CE->getValue(); + return Value == 1 || Value == 0; + } bool isReg() const { return Kind == Register; } bool isRegList() const { return Kind == RegisterList; } bool isDPRRegList() const { return Kind == DPRRegisterList; } @@ -715,6 +724,11 @@ public: addExpr(Inst, getImm()); } + void addSetEndImmOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + addExpr(Inst, getImm()); + } + void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt()))); @@ -1644,6 +1658,30 @@ parsePKHImm(SmallVectorImpl &Operands, StringRef Op, return MatchOperand_Success; } +ARMAsmParser::OperandMatchResultTy ARMAsmParser:: +parseSetEndImm(SmallVectorImpl &Operands) { + const AsmToken &Tok = Parser.getTok(); + SMLoc S = Tok.getLoc(); + if (Tok.isNot(AsmToken::Identifier)) { + Error(Tok.getLoc(), "'be' or 'le' operand expected"); + return MatchOperand_ParseFail; + } + int Val = StringSwitch(Tok.getString()) + .Case("be", 1) + .Case("le", 0) + .Default(-1); + Parser.Lex(); // Eat the token. + + if (Val == -1) { + Error(Tok.getLoc(), "'be' or 'le' operand expected"); + return MatchOperand_ParseFail; + } + Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val, + getContext()), + S, Parser.getTok().getLoc())); + return MatchOperand_Success; +} + /// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. @@ -2197,6 +2235,7 @@ GetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" || Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" || Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "clrex" || + Mnemonic == "setend" || Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumb())) { CanAcceptPredicationCode = false; } else { @@ -2221,7 +2260,7 @@ bool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, unsigned ProcessorIMod; bool CarrySetting; Mnemonic = SplitMnemonic(Mnemonic, PredicationCode, CarrySetting, - ProcessorIMod); + ProcessorIMod); Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc)); @@ -2245,6 +2284,13 @@ bool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, return Error(NameLoc, "instruction '" + Mnemonic + "' can not set flags, but 's' suffix specified"); } + // If we had a predication code on an instruction that can't do that, issue an + // error. + if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) { + Parser.EatToEndOfStatement(); + return Error(NameLoc, "instruction '" + Mnemonic + + "' is not predicable, but condition code specified"); + } // Add the carry setting operand, if necessary. // @@ -2259,11 +2305,6 @@ bool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, if (CanAcceptPredicationCode) { Operands.push_back(ARMOperand::CreateCondCode( ARMCC::CondCodes(PredicationCode), NameLoc)); - } else { - // This mnemonic can't ever accept a predication code, but the user wrote - // one (or misspelled another mnemonic). - - // FIXME: Issue a nice error. } // Add the processor imod operand, if necessary. diff --git a/test/MC/ARM/basic-arm-instructions.s b/test/MC/ARM/basic-arm-instructions.s index 0bde0f63595..00087f3a667 100644 --- a/test/MC/ARM/basic-arm-instructions.s +++ b/test/MC/ARM/basic-arm-instructions.s @@ -1303,6 +1303,16 @@ _func: @ CHECK: selne r9, r2, r1 @ encoding: [0xb1,0x9f,0x82,0x16] +@------------------------------------------------------------------------------ +@ SETEND +@------------------------------------------------------------------------------ + setend be + setend le + + sel r9, r2, r1 @ encoding: [0xb1,0x9f,0x82,0xe6] + selne r9, r2, r1 @ encoding: [0xb1,0x9f,0x82,0x16] + + @------------------------------------------------------------------------------ @ STM* @------------------------------------------------------------------------------ diff --git a/test/MC/ARM/diagnostics.s b/test/MC/ARM/diagnostics.s index abefca60afd..305a5fa65e1 100644 --- a/test/MC/ARM/diagnostics.s +++ b/test/MC/ARM/diagnostics.s @@ -144,3 +144,19 @@ @ CHECK: error: asr operand expected. @ CHECK: pkhtb r2, r2, r3, lsl #3 @ CHECK: ^ + + + @ bad values for SETEND + setendne be + setend me + setend 1 + +@ CHECK: error: instruction 'setend' is not predicable, but condition code specified +@ CHECK: setendne be +@ CHECK: ^ +@ CHECK: error: 'be' or 'le' operand expected +@ CHECK: setend me +@ CHECK: ^ +@ CHECK: error: 'be' or 'le' operand expected +@ CHECK: setend 1 +@ CHECK: ^