From 14ce6fac242228dacc5c08040e544141a96880e5 Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Tue, 24 Apr 2012 22:40:08 +0000 Subject: ARM: improved assembler diagnostics for missing CPU features. When an instruction match is found, but the subtarget features it requires are not available (missing floating point unit, or thumb vs arm mode, for example), issue a diagnostic that identifies what the feature mismatch is. rdar://11257547 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155499 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'lib/Target/ARM/AsmParser') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 2c53e3f..cbd9bdb 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -7277,6 +7277,7 @@ unsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) { return Match_Success; } +static const char *getSubtargetFeatureName(unsigned Val); bool ARMAsmParser:: MatchAndEmitInstruction(SMLoc IDLoc, SmallVectorImpl &Operands, @@ -7317,9 +7318,21 @@ MatchAndEmitInstruction(SMLoc IDLoc, Inst.setLoc(IDLoc); Out.EmitInstruction(Inst); return false; - case Match_MissingFeature: - Error(IDLoc, "instruction requires a CPU feature not currently enabled"); - return true; + case Match_MissingFeature: { + assert(ErrorInfo && "Unknown missing feature!"); + // Special case the error message for the very common case where only + // a single subtarget feature is missing (Thumb vs. ARM, e.g.). + std::string Msg = "instruction requires:"; + unsigned Mask = 1; + for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) { + if (ErrorInfo & Mask) { + Msg += " "; + Msg += getSubtargetFeatureName(ErrorInfo & Mask); + } + Mask <<= 1; + } + return Error(IDLoc, Msg); + } case Match_InvalidOperand: { SMLoc ErrorLoc = IDLoc; if (ErrorInfo != ~0U) { -- cgit v1.1 From 8030e1a0df630ec6ed1cd5ec673f6472558a4dbe Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 25 Apr 2012 06:56:34 +0000 Subject: Add ifdef around getSubtargetFeatureName in tablegen output file so that only targets that want the function get it. This prevents other targets from getting an unused function warning. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155538 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/Target/ARM/AsmParser') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index cbd9bdb..3fe681f 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -7595,5 +7595,6 @@ extern "C" void LLVMInitializeARMAsmParser() { } #define GET_REGISTER_MATCHER +#define GET_SUBTARGET_FEATURE_NAME #define GET_MATCHER_IMPLEMENTATION #include "ARMGenAsmMatcher.inc" -- cgit v1.1 From b56e4115ed33dae56108ed4ce88ee3a0e0392bfc Mon Sep 17 00:00:00 2001 From: Richard Barton Date: Wed, 25 Apr 2012 18:00:18 +0000 Subject: Unify internal representation of ARM instructions with a register right-shifted by #32. These are stored as shifts by #0 in the MCInst and correctly marshalled when transforming from or to assembly representation. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155565 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'lib/Target/ARM/AsmParser') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 3fe681f..69c9d45 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -1446,8 +1446,10 @@ public: assert(isRegShiftedImm() && "addRegShiftedImmOperands() on non RegShiftedImm!"); Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg)); + // Shift of #32 is encoded as 0 where permitted + unsigned Imm = (RegShiftedImm.ShiftImm == 32 ? 0 : RegShiftedImm.ShiftImm); Inst.addOperand(MCOperand::CreateImm( - ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm))); + ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, Imm))); } void addShifterImmOperands(MCInst &Inst, unsigned N) const { @@ -6809,6 +6811,9 @@ processInstruction(MCInst &Inst, // A shift by zero is a plain MOVr, not a MOVsi. unsigned Amt = Inst.getOperand(2).getImm(); unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi; + // A shift by 32 should be encoded as 0 when permitted + if (Amt == 32 && (ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr)) + Amt = 0; unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, Amt); MCInst TmpInst; TmpInst.setOpcode(Opc); @@ -7154,7 +7159,9 @@ processInstruction(MCInst &Inst, } case ARM::MOVsi: { ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Inst.getOperand(2).getImm()); - if (SOpc == ARM_AM::rrx) return false; + // rrx shifts and asr/lsr of #32 is encoded as 0 + if (SOpc == ARM_AM::rrx || SOpc == ARM_AM::asr || SOpc == ARM_AM::lsr) + return false; if (ARM_AM::getSORegOffset(Inst.getOperand(2).getImm()) == 0) { // Shifting by zero is accepted as a vanilla 'MOVr' MCInst TmpInst; -- cgit v1.1 From 4d2f077df1b46a126b5595d983f233ec896b757e Mon Sep 17 00:00:00 2001 From: Richard Barton Date: Fri, 27 Apr 2012 08:42:59 +0000 Subject: Refactor IT handling not to store the bottom bit of the condition code in the mask operand in the MCInst. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155700 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'lib/Target/ARM/AsmParser') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 69c9d45..fdefe43 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -7214,9 +7214,7 @@ processInstruction(MCInst &Inst, // The mask bits for all but the first condition are represented as // the low bit of the condition code value implies 't'. We currently // always have 1 implies 't', so XOR toggle the bits if the low bit - // of the condition code is zero. The encoding also expects the low - // bit of the condition to be encoded as bit 4 of the mask operand, - // so mask that in if needed + // of the condition code is zero. MCOperand &MO = Inst.getOperand(1); unsigned Mask = MO.getImm(); unsigned OrigMask = Mask; @@ -7225,8 +7223,7 @@ processInstruction(MCInst &Inst, assert(Mask && TZ <= 3 && "illegal IT mask value!"); for (unsigned i = 3; i != TZ; --i) Mask ^= 1 << i; - } else - Mask |= 0x10; + } MO.setImm(Mask); // Set up the IT block state according to the IT instruction we just -- cgit v1.1 From 04a09a461beb4ec629fe53e601b7665547ac35c3 Mon Sep 17 00:00:00 2001 From: Richard Barton Date: Fri, 27 Apr 2012 17:34:01 +0000 Subject: Fix ARM assembly parsing for upper case condition codes on IT instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155720 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/Target/ARM/AsmParser') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index fdefe43..57c76d8 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -2674,7 +2674,7 @@ parseITCondCode(SmallVectorImpl &Operands) { const AsmToken &Tok = Parser.getTok(); if (!Tok.is(AsmToken::Identifier)) return MatchOperand_NoMatch; - unsigned CC = StringSwitch(Tok.getString()) + unsigned CC = StringSwitch(Tok.getString().lower()) .Case("eq", ARMCC::EQ) .Case("ne", ARMCC::NE) .Case("hs", ARMCC::HS) -- cgit v1.1 From a9cc08f24f61e2663a131d7ac16c329b75162e7b Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Fri, 27 Apr 2012 23:51:36 +0000 Subject: ARM: Thumb add(sp plus register) asm constraints. Make sure when parsing the Thumb1 sp+register ADD instruction that the source and destination operands match. In thumb2, just use the wide encoding if they don't. In Thumb1, issue a diagnostic. rdar://11219154 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155748 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'lib/Target/ARM/AsmParser') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 57c76d8..7822501 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -5317,6 +5317,16 @@ validateInstruction(MCInst &Inst, "registers must be in range r0-r7"); break; } + case ARM::tADDrSP: { + // If the non-SP source operand and the destination operand are not the + // same, we need thumb2 (for the wide encoding), or we have an error. + if (!isThumbTwo() && + Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) { + return Error(Operands[4]->getStartLoc(), + "source register must be the same as destination"); + } + break; + } } return false; @@ -6990,6 +7000,16 @@ processInstruction(MCInst &Inst, Inst = TmpInst; return true; } + case ARM::tADDrSP: { + // If the non-SP source operand and the destination operand are not the + // same, we need to use the 32-bit encoding if it's available. + if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) { + Inst.setOpcode(ARM::t2ADDrr); + Inst.addOperand(MCOperand::CreateReg(0)); // cc_out + return true; + } + break; + } case ARM::tB: // A Thumb conditional branch outside of an IT block is a tBcc. if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) { -- cgit v1.1 From ca3cd419a52c1dedee133d79772ef97f30e5d20b Mon Sep 17 00:00:00 2001 From: Silviu Baranga Date: Fri, 11 May 2012 09:10:54 +0000 Subject: Fixed the LLVM ARM v7 assembler and instruction printer for 8-bit immediate offset addressing. The assembler and instruction printer were not properly handeling the #-0 immediate. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156608 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib/Target/ARM/AsmParser') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 7822501..8865979 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -914,7 +914,9 @@ public: // Immediate offset in range [-255, 255]. if (!Memory.OffsetImm) return true; int64_t Val = Memory.OffsetImm->getValue(); - return Val > -256 && Val < 256; + // The #-0 offset is encoded as INT32_MIN, and we have to check + // for this too. + return (Val > -256 && Val < 256) || Val == INT32_MIN; } bool isAM3Offset() const { if (Kind != k_Immediate && Kind != k_PostIndexRegister) -- cgit v1.1 From 0fd4f3c8de07e9cfe2a86093ccada82d64f38bfe Mon Sep 17 00:00:00 2001 From: Kevin Enderby Date: Thu, 17 May 2012 22:18:01 +0000 Subject: Fix the encoding of the armv7m (MClass) for MSR APSR writes which was missing the 0b10 mask encoding bits. Make MSR APSR writes without a _ qualifier an alias for MSR APSR_nzcvq even though ARM as deprecated it use. Also add support for suffixes (_nzcvq, _g, _nzcvqg) for APSR versions. Some FIXMEs in the code for better error checking when versions shouldn't be used. rdar://11457025 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157019 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 33 +++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) (limited to 'lib/Target/ARM/AsmParser') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 8865979..00e7f6e 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -3324,10 +3324,35 @@ parseMSRMaskOperand(SmallVectorImpl &Operands) { // See ARMv6-M 10.1.1 std::string Name = Mask.lower(); unsigned FlagsVal = StringSwitch(Name) - .Case("apsr", 0) - .Case("iapsr", 1) - .Case("eapsr", 2) - .Case("xpsr", 3) + // Note: in the documentation: + // ARM deprecates using MSR APSR without a _ qualifier as an alias + // for MSR APSR_nzcvq. + // but we do make it an alias here. This is so to get the "mask encoding" + // bits correct on MSR APSR writes. + // + // FIXME: Note the 0xc00 "mask encoding" bits version of the registers + // should really only be allowed when writing a special register. Note + // they get dropped in the MRS instruction reading a special register as + // the SYSm field is only 8 bits. + // + // FIXME: the _g and _nzcvqg versions are only allowed if the processor + // includes the DSP extension but that is not checked. + .Case("apsr", 0x800) + .Case("apsr_nzcvq", 0x800) + .Case("apsr_g", 0x400) + .Case("apsr_nzcvqg", 0xc00) + .Case("iapsr", 0x801) + .Case("iapsr_nzcvq", 0x801) + .Case("iapsr_g", 0x401) + .Case("iapsr_nzcvqg", 0xc01) + .Case("eapsr", 0x802) + .Case("eapsr_nzcvq", 0x802) + .Case("eapsr_g", 0x402) + .Case("eapsr_nzcvqg", 0xc02) + .Case("xpsr", 0x803) + .Case("xpsr_nzcvq", 0x803) + .Case("xpsr_g", 0x403) + .Case("xpsr_nzcvqg", 0xc03) .Case("ipsr", 5) .Case("epsr", 6) .Case("iepsr", 7) -- cgit v1.1 From 032f441afcdd70eb6bda477d32e8c372443b4e6f Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Thu, 24 May 2012 04:11:15 +0000 Subject: Mark a static array as const. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157368 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/Target/ARM/AsmParser') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 00e7f6e..86985d2 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -2305,7 +2305,7 @@ void ARMOperand::print(raw_ostream &OS) const { OS << ""; break; case k_ITCondMask: { - static const char *MaskStr[] = { + static const char *const MaskStr[] = { "()", "(t)", "(e)", "(tt)", "(et)", "(te)", "(ee)", "(ttt)", "(ett)", "(tet)", "(eet)", "(tte)", "(ete)", "(tee)", "(eee)" }; -- cgit v1.1 From d9b0b025612992a0b724eeca8bdf10b1d7a5c355 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Sat, 2 Jun 2012 10:20:22 +0000 Subject: Fix typos found by http://github.com/lyda/misspell-check git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157885 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/Target/ARM/AsmParser') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 86985d2..2fae489 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -6789,8 +6789,8 @@ processInstruction(MCInst &Inst, case ARM_AM::ror: newOpc = ARM::t2RORri; isNarrow = false; break; case ARM_AM::rrx: isNarrow = false; newOpc = ARM::t2RRX; break; } - unsigned Ammount = ARM_AM::getSORegOffset(Inst.getOperand(2).getImm()); - if (Ammount == 32) Ammount = 0; + unsigned Amount = ARM_AM::getSORegOffset(Inst.getOperand(2).getImm()); + if (Amount == 32) Amount = 0; TmpInst.setOpcode(newOpc); TmpInst.addOperand(Inst.getOperand(0)); // Rd if (isNarrow) @@ -6798,7 +6798,7 @@ processInstruction(MCInst &Inst, Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0)); TmpInst.addOperand(Inst.getOperand(1)); // Rn if (newOpc != ARM::t2RRX) - TmpInst.addOperand(MCOperand::CreateImm(Ammount)); + TmpInst.addOperand(MCOperand::CreateImm(Amount)); TmpInst.addOperand(Inst.getOperand(3)); // CondCode TmpInst.addOperand(Inst.getOperand(4)); if (!isNarrow) @@ -7400,7 +7400,7 @@ MatchAndEmitInstruction(SMLoc IDLoc, return Error(IDLoc, "invalid instruction", ((ARMOperand*)Operands[0])->getLocRange()); case Match_ConversionFail: - // The converter function will have already emited a diagnostic. + // The converter function will have already emitted a diagnostic. return true; case Match_RequiresNotITBlock: return Error(IDLoc, "flag setting instruction only valid outside IT block"); -- cgit v1.1 From a1c7367a5bed459acc88e3ea2a482b4b5dac942a Mon Sep 17 00:00:00 2001 From: Richard Barton Date: Thu, 14 Jun 2012 10:48:04 +0000 Subject: Replace assertion failure for badly formatted CPS instrution with error message. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@158445 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/Target/ARM/AsmParser') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 2fae489..6e0062a 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -3284,7 +3284,8 @@ ARMAsmParser::OperandMatchResultTy ARMAsmParser:: parseProcIFlagsOperand(SmallVectorImpl &Operands) { SMLoc S = Parser.getTok().getLoc(); const AsmToken &Tok = Parser.getTok(); - assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); + if (!Tok.is(AsmToken::Identifier)) + return MatchOperand_NoMatch; StringRef IFlagsStr = Tok.getString(); // An iflags string of "none" is interpreted to mean that none of the AIF -- cgit v1.1 From f49a4092bcf679d1634a8023efc593e98a3e5663 Mon Sep 17 00:00:00 2001 From: Kevin Enderby Date: Fri, 15 Jun 2012 22:14:44 +0000 Subject: Fix the encoding of the armv7m (MClass) for MSR registers other than aspr, iaspr, espr and xpsr which also needed to have 0b10 in their mask encoding bits. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@158560 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'lib/Target/ARM/AsmParser') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 6e0062a..fd0186d 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -3354,22 +3354,22 @@ parseMSRMaskOperand(SmallVectorImpl &Operands) { .Case("xpsr_nzcvq", 0x803) .Case("xpsr_g", 0x403) .Case("xpsr_nzcvqg", 0xc03) - .Case("ipsr", 5) - .Case("epsr", 6) - .Case("iepsr", 7) - .Case("msp", 8) - .Case("psp", 9) - .Case("primask", 16) - .Case("basepri", 17) - .Case("basepri_max", 18) - .Case("faultmask", 19) - .Case("control", 20) + .Case("ipsr", 0x805) + .Case("epsr", 0x806) + .Case("iepsr", 0x807) + .Case("msp", 0x808) + .Case("psp", 0x809) + .Case("primask", 0x810) + .Case("basepri", 0x811) + .Case("basepri_max", 0x812) + .Case("faultmask", 0x813) + .Case("control", 0x814) .Default(~0U); if (FlagsVal == ~0U) return MatchOperand_NoMatch; - if (!hasV7Ops() && FlagsVal >= 17 && FlagsVal <= 19) + if (!hasV7Ops() && FlagsVal >= 0x811 && FlagsVal <= 0x813) // basepri, basepri_max and faultmask only valid for V7m. return MatchOperand_NoMatch; -- cgit v1.1 From 70c9bf3c1a77b5707c92a7cfe74104c320480391 Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Fri, 22 Jun 2012 23:56:48 +0000 Subject: ARM: Add a better diagnostic for some out of range immediates. As an example of how the custom DiagnosticType can be used to provide better operand-mismatch diagnostics, add a custom diagnostic for the imm0_15 operand class used for several system instructions. Update the tests to expect the improved diagnostic. rdar://8987109 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@159051 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'lib/Target/ARM/AsmParser') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index fd0186d..d375e35 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -236,7 +236,10 @@ public: Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY, Match_RequiresNotITBlock, Match_RequiresV6, - Match_RequiresThumb2 + Match_RequiresThumb2, +#define GET_OPERAND_DIAGNOSTIC_TYPES +#include "ARMGenAsmMatcher.inc" + }; ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) @@ -7411,6 +7414,11 @@ MatchAndEmitInstruction(SMLoc IDLoc, return Error(IDLoc, "instruction variant requires ARMv6 or later"); case Match_RequiresThumb2: return Error(IDLoc, "instruction variant requires Thumb2"); + case Match_ImmRange0_15: { + SMLoc ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); + if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; + return Error(ErrorLoc, "immediate operand must be in the range [0,15]"); + } } llvm_unreachable("Implement any new match types added!"); -- cgit v1.1 From b69182095ce19c07a7207ab546f61bffc5111d8e Mon Sep 17 00:00:00 2001 From: Richard Barton Date: Wed, 27 Jun 2012 09:36:19 +0000 Subject: Prevent ARM Assembler crashing on unrecognised assembly format for DSB instruction git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@159257 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/Target/ARM/AsmParser') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index d375e35..830e9c0 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -3256,7 +3256,8 @@ ARMAsmParser::OperandMatchResultTy ARMAsmParser:: parseMemBarrierOptOperand(SmallVectorImpl &Operands) { SMLoc S = Parser.getTok().getLoc(); const AsmToken &Tok = Parser.getTok(); - assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); + if (!Tok.is(AsmToken::Identifier)) + return MatchOperand_NoMatch; StringRef OptStr = Tok.getString(); unsigned Opt = StringSwitch(OptStr.slice(0, OptStr.size())) -- cgit v1.1 From 4acefe192f02849bcb2fd620a9f507c00d39a686 Mon Sep 17 00:00:00 2001 From: Richard Barton Date: Wed, 27 Jun 2012 09:48:23 +0000 Subject: Teach assembler to handle capitalised operation values for DSB instructions git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@159259 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/Target/ARM/AsmParser') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 830e9c0..68f1281 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -3260,7 +3260,7 @@ parseMemBarrierOptOperand(SmallVectorImpl &Operands) { return MatchOperand_NoMatch; StringRef OptStr = Tok.getString(); - unsigned Opt = StringSwitch(OptStr.slice(0, OptStr.size())) + unsigned Opt = StringSwitch(OptStr.slice(0, OptStr.size()).lower()) .Case("sy", ARM_MB::SY) .Case("st", ARM_MB::ST) .Case("sh", ARM_MB::ISH) -- cgit v1.1 From 2b6652fb10d7005e41010b0e0800afe16ae18a34 Mon Sep 17 00:00:00 2001 From: Richard Barton Date: Mon, 9 Jul 2012 16:12:24 +0000 Subject: Teach the assembler to use the narrow thumb encodings of various three-register dp instructions where permissable. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@159935 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 80 +++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) (limited to 'lib/Target/ARM/AsmParser') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 68f1281..769e3aa 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -7287,6 +7287,86 @@ processInstruction(MCInst &Inst, ITState.FirstCond = true; break; } + case ARM::t2LSLrr: + case ARM::t2LSRrr: + case ARM::t2ASRrr: + case ARM::t2SBCrr: + case ARM::t2RORrr: + case ARM::t2BICrr: + { + // Assemblers should use the narrow encodings of these instructions when permissable. + if ((isARMLowRegister(Inst.getOperand(1).getReg()) && + isARMLowRegister(Inst.getOperand(2).getReg())) && + Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() && + (!inITBlock() && Inst.getOperand(5).getReg() == ARM::CPSR || + inITBlock() && Inst.getOperand(5).getReg() != ARM::CPSR) && + (!static_cast(Operands[3])->isToken() || + !static_cast(Operands[3])->getToken().equals_lower(".w"))) { + unsigned NewOpc; + switch (Inst.getOpcode()) { + default: llvm_unreachable("unexpected opcode"); + case ARM::t2LSLrr: NewOpc = ARM::tLSLrr; break; + case ARM::t2LSRrr: NewOpc = ARM::tLSRrr; break; + case ARM::t2ASRrr: NewOpc = ARM::tASRrr; break; + case ARM::t2SBCrr: NewOpc = ARM::tSBC; break; + case ARM::t2RORrr: NewOpc = ARM::tROR; break; + case ARM::t2BICrr: NewOpc = ARM::tBIC; break; + } + MCInst TmpInst; + TmpInst.setOpcode(NewOpc); + TmpInst.addOperand(Inst.getOperand(0)); + TmpInst.addOperand(Inst.getOperand(5)); + TmpInst.addOperand(Inst.getOperand(1)); + TmpInst.addOperand(Inst.getOperand(2)); + TmpInst.addOperand(Inst.getOperand(3)); + TmpInst.addOperand(Inst.getOperand(4)); + Inst = TmpInst; + return true; + } + return false; + } + case ARM::t2ANDrr: + case ARM::t2EORrr: + case ARM::t2ADCrr: + case ARM::t2ORRrr: + { + // Assemblers should use the narrow encodings of these instructions when permissable. + // These instructions are special in that they are commutable, so shorter encodings + // are available more often. + if ((isARMLowRegister(Inst.getOperand(1).getReg()) && + isARMLowRegister(Inst.getOperand(2).getReg())) && + (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() || + Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg()) && + (!inITBlock() && Inst.getOperand(5).getReg() == ARM::CPSR || + inITBlock() && Inst.getOperand(5).getReg() != ARM::CPSR) && + (!static_cast(Operands[3])->isToken() || + !static_cast(Operands[3])->getToken().equals_lower(".w"))) { + unsigned NewOpc; + switch (Inst.getOpcode()) { + default: llvm_unreachable("unexpected opcode"); + case ARM::t2ADCrr: NewOpc = ARM::tADC; break; + case ARM::t2ANDrr: NewOpc = ARM::tAND; break; + case ARM::t2EORrr: NewOpc = ARM::tEOR; break; + case ARM::t2ORRrr: NewOpc = ARM::tORR; break; + } + MCInst TmpInst; + TmpInst.setOpcode(NewOpc); + TmpInst.addOperand(Inst.getOperand(0)); + TmpInst.addOperand(Inst.getOperand(5)); + if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()) { + TmpInst.addOperand(Inst.getOperand(1)); + TmpInst.addOperand(Inst.getOperand(2)); + } else { + TmpInst.addOperand(Inst.getOperand(2)); + TmpInst.addOperand(Inst.getOperand(1)); + } + TmpInst.addOperand(Inst.getOperand(3)); + TmpInst.addOperand(Inst.getOperand(4)); + Inst = TmpInst; + return true; + } + return false; + } } return false; } -- cgit v1.1 From c985e6ece66cf2046f0113da9eb2dec331a6b09f Mon Sep 17 00:00:00 2001 From: Richard Barton Date: Mon, 9 Jul 2012 16:14:28 +0000 Subject: Spelling! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@159936 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/Target/ARM/AsmParser') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 769e3aa..b084265 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -7294,7 +7294,7 @@ processInstruction(MCInst &Inst, case ARM::t2RORrr: case ARM::t2BICrr: { - // Assemblers should use the narrow encodings of these instructions when permissable. + // Assemblers should use the narrow encodings of these instructions when permissible. if ((isARMLowRegister(Inst.getOperand(1).getReg()) && isARMLowRegister(Inst.getOperand(2).getReg())) && Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() && @@ -7330,7 +7330,7 @@ processInstruction(MCInst &Inst, case ARM::t2ADCrr: case ARM::t2ORRrr: { - // Assemblers should use the narrow encodings of these instructions when permissable. + // Assemblers should use the narrow encodings of these instructions when permissible. // These instructions are special in that they are commutable, so shorter encodings // are available more often. if ((isARMLowRegister(Inst.getOperand(1).getReg()) && -- cgit v1.1 From 8ed97ef5f6980c689a5770ec30488601201e17c3 Mon Sep 17 00:00:00 2001 From: Richard Barton Date: Mon, 9 Jul 2012 16:31:14 +0000 Subject: Prevent ARM assembler from losing a right shift by #32 applied to a register git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@159937 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib/Target/ARM/AsmParser') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index b084265..7901253 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -7247,7 +7247,9 @@ processInstruction(MCInst &Inst, case ARM::ADDrsi: newOpc = ARM::ADDrr; break; } // If the shift is by zero, use the non-shifted instruction definition. - if (ARM_AM::getSORegOffset(Inst.getOperand(3).getImm()) == 0) { + // The exception is for right shifts, where 0 == 32 + if (ARM_AM::getSORegOffset(Inst.getOperand(3).getImm()) == 0 && + !(SOpc == ARM_AM::lsr || SOpc == ARM_AM::asr)) { MCInst TmpInst; TmpInst.setOpcode(newOpc); TmpInst.addOperand(Inst.getOperand(0)); -- cgit v1.1 From 874b863f2ab9158db6f7f1b773b77e6334e31c41 Mon Sep 17 00:00:00 2001 From: Richard Barton Date: Mon, 9 Jul 2012 18:30:56 +0000 Subject: Some formatting to keep Clang happy git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@159948 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/Target/ARM/AsmParser') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 7901253..4497720 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -7300,8 +7300,8 @@ processInstruction(MCInst &Inst, if ((isARMLowRegister(Inst.getOperand(1).getReg()) && isARMLowRegister(Inst.getOperand(2).getReg())) && Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() && - (!inITBlock() && Inst.getOperand(5).getReg() == ARM::CPSR || - inITBlock() && Inst.getOperand(5).getReg() != ARM::CPSR) && + ((!inITBlock() && Inst.getOperand(5).getReg() == ARM::CPSR) || + (inITBlock() && Inst.getOperand(5).getReg() != ARM::CPSR)) && (!static_cast(Operands[3])->isToken() || !static_cast(Operands[3])->getToken().equals_lower(".w"))) { unsigned NewOpc; @@ -7339,8 +7339,8 @@ processInstruction(MCInst &Inst, isARMLowRegister(Inst.getOperand(2).getReg())) && (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() || Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg()) && - (!inITBlock() && Inst.getOperand(5).getReg() == ARM::CPSR || - inITBlock() && Inst.getOperand(5).getReg() != ARM::CPSR) && + ((!inITBlock() && Inst.getOperand(5).getReg() == ARM::CPSR) || + (inITBlock() && Inst.getOperand(5).getReg() != ARM::CPSR)) && (!static_cast(Operands[3])->isToken() || !static_cast(Operands[3])->getToken().equals_lower(".w"))) { unsigned NewOpc; -- cgit v1.1