From: Jim Grosbach Date: Tue, 19 Jul 2011 20:10:31 +0000 (+0000) Subject: ARM assembly parsing for MOV (register). X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=5f16057d1e4b711d492091bc555693a03d4a1b6e;p=oota-llvm.git ARM assembly parsing for MOV (register). Correct the handling of the 's' suffix when parsing ARM mode. It's only a truly separate opcode in Thumb. Add test cases to make sure we handle the s and condition suffices correctly, including diagnostics. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135513 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 4a0c388d914..752e90af775 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -79,6 +79,8 @@ class ARMAsmParser : public TargetAsmParser { bool MatchAndEmitInstruction(SMLoc IDLoc, SmallVectorImpl &Operands, MCStreamer &Out); + StringRef SplitMnemonic(StringRef Mnemonic, unsigned &PredicationCode, + bool &CarrySetting, unsigned &ProcessorIMod); void GetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, bool &CanAcceptPredicationCode); @@ -1952,10 +1954,10 @@ ARMAsmParser::ApplyPrefixToExpr(const MCExpr *E, /// setting letters to form a canonical mnemonic and flags. // // FIXME: Would be nice to autogen this. -static StringRef SplitMnemonic(StringRef Mnemonic, - unsigned &PredicationCode, - bool &CarrySetting, - unsigned &ProcessorIMod) { +StringRef ARMAsmParser::SplitMnemonic(StringRef Mnemonic, + unsigned &PredicationCode, + bool &CarrySetting, + unsigned &ProcessorIMod) { PredicationCode = ARMCC::AL; CarrySetting = false; ProcessorIMod = 0; @@ -1963,19 +1965,19 @@ static StringRef SplitMnemonic(StringRef Mnemonic, // Ignore some mnemonics we know aren't predicated forms. // // FIXME: Would be nice to autogen this. - if (Mnemonic == "teq" || Mnemonic == "vceq" || Mnemonic == "movs" || - Mnemonic == "svc" || Mnemonic == "mls" || Mnemonic == "smmls" || - Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vnmls" || - Mnemonic == "vacge" || Mnemonic == "vcge" || Mnemonic == "vclt" || - Mnemonic == "vacgt" || Mnemonic == "vcgt" || Mnemonic == "vcle" || - Mnemonic == "smlal" || Mnemonic == "umaal" || Mnemonic == "umlal" || - Mnemonic == "vabal" || Mnemonic == "vmlal" || Mnemonic == "vpadal" || - Mnemonic == "vqdmlal") + if ((Mnemonic == "movs" && isThumb()) || + Mnemonic == "teq" || Mnemonic == "vceq" || Mnemonic == "svc" || + Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" || + Mnemonic == "vmls" || Mnemonic == "vnmls" || Mnemonic == "vacge" || + Mnemonic == "vcge" || Mnemonic == "vclt" || Mnemonic == "vacgt" || + Mnemonic == "vcgt" || Mnemonic == "vcle" || Mnemonic == "smlal" || + Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" || + Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal") return Mnemonic; // First, split out any predication code. Ignore mnemonics we know aren't // predicated but do have a carry-set and so weren't caught above. - if (Mnemonic != "adcs" && Mnemonic != "bics") { + if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs") { unsigned CC = StringSwitch(Mnemonic.substr(Mnemonic.size()-2)) .Case("eq", ARMCC::EQ) .Case("ne", ARMCC::NE) @@ -2005,10 +2007,10 @@ static StringRef SplitMnemonic(StringRef Mnemonic, // the instructions we know end in 's'. if (Mnemonic.endswith("s") && !(Mnemonic == "asrs" || Mnemonic == "cps" || Mnemonic == "mls" || - Mnemonic == "movs" || Mnemonic == "mrs" || Mnemonic == "smmls" || - Mnemonic == "vabs" || Mnemonic == "vcls" || Mnemonic == "vmls" || - Mnemonic == "vmrs" || Mnemonic == "vnmls" || Mnemonic == "vqabs" || - Mnemonic == "vrecps" || Mnemonic == "vrsqrts")) { + Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" || + Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" || + Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" || + Mnemonic == "vrsqrts" || (Mnemonic == "movs" && isThumb()))) { Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); CarrySetting = true; } @@ -2056,8 +2058,8 @@ GetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" || Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" || Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" || - Mnemonic == "dsb" || Mnemonic == "movs" || Mnemonic == "isb" || - Mnemonic == "clrex" || Mnemonic.startswith("cps")) { + Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "clrex" || + Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumb())) { CanAcceptPredicationCode = false; } else { CanAcceptPredicationCode = true; diff --git a/test/MC/ARM/basic-arm-instructions.s b/test/MC/ARM/basic-arm-instructions.s index f54723a4f52..3bc061127a4 100644 --- a/test/MC/ARM/basic-arm-instructions.s +++ b/test/MC/ARM/basic-arm-instructions.s @@ -678,12 +678,31 @@ _func: mov r5, #0xff0000 mov r6, #0xffff movw r9, #0xffff + movs r3, #7 + moveq r4, #0xff0 + movseq r5, #0xff0000 @ CHECK: mov r3, #7 @ encoding: [0x07,0x30,0xa0,0xe3] @ CHECK: mov r4, #4080 @ encoding: [0xff,0x4e,0xa0,0xe3] @ CHECK: mov r5, #16711680 @ encoding: [0xff,0x58,0xa0,0xe3] @ CHECK: movw r6, #65535 @ encoding: [0xff,0x6f,0x0f,0xe3] @ CHECK: movw r9, #65535 @ encoding: [0xff,0x9f,0x0f,0xe3] +@ CHECK: movs r3, #7 @ encoding: [0x07,0x30,0xb0,0xe3] +@ CHECK: moveq r4, #4080 @ encoding: [0xff,0x4e,0xa0,0x03] +@ CHECK: movseq r5, #16711680 @ encoding: [0xff,0x58,0xb0,0x03] + +@------------------------------------------------------------------------------ +@ MOV (register) +@------------------------------------------------------------------------------ + mov r2, r3 + movs r2, r3 + moveq r2, r3 + movseq r2, r3 + +@ CHECK: mov r2, r3 @ encoding: [0x03,0x20,0xa0,0xe1] +@ CHECK: movs r2, r3 @ encoding: [0x03,0x20,0xb0,0xe1] +@ CHECK: moveq r2, r3 @ encoding: [0x03,0x20,0xa0,0x01] +@ CHECK: movseq r2, r3 @ encoding: [0x03,0x20,0xb0,0x01] @------------------------------------------------------------------------------ @ STM* diff --git a/test/MC/ARM/diagnostics.s b/test/MC/ARM/diagnostics.s index 1ae41ebb6c9..08c982e182f 100644 --- a/test/MC/ARM/diagnostics.s +++ b/test/MC/ARM/diagnostics.s @@ -93,3 +93,9 @@ @ Out of range immediate for MOV movw r9, 0x10000 @ CHECK-ERRORS: error: invalid operand for instruction + + @ Invalid 's' bit usage for MOVW + movs r6, #0xffff + movwseq r9, #0xffff +@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-ERRORS: error: instruction 'movw' can not set flags, but 's' suffix specified